home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / system-config-printer / system-config-printer.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-10-28  |  181.4 KB  |  6,563 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import config
  5. import errno
  6. import sys
  7. import os
  8. import tempfile
  9. import time
  10. import traceback
  11. import re
  12. import httplib
  13. import glob
  14. import subprocess
  15. import signal
  16. import thread
  17. from timedops import *
  18. import dbus
  19.  
  20. try:
  21.     import gtk.glade as gtk
  22. except RuntimeError:
  23.     e = None
  24.     print 'system-config-printer:', e
  25.     print 'This is a graphical application and requires DISPLAY to be set.'
  26.     sys.exit(1)
  27.  
  28. import glib
  29.  
  30. def show_uri(uri):
  31.     gtk.show_uri(gtk.gdk.screen_get_default(), uri, gtk.get_current_event_time())
  32.  
  33. gtk.about_dialog_set_url_hook((lambda x, y: show_uri(y)))
  34. gtk.about_dialog_set_email_hook((lambda x, y: show_uri('mailto:' + y)))
  35.  
  36. def show_help():
  37.     print '\nThis is system-config-printer, a CUPS server configuration program.\n\nOptions:\n\n  --setup-printer URI\n            Select the (detected) CUPS device URI on start-up,\n            and run the new-printer wizard for it.\n\n  --configure-printer NAME\n            Select the named printer on start-up, and open its\n            properties dialog.\n\n  --choose-driver NAME\n            Select the named printer on start-up, and display\n            the list of drivers.\n\n  --print-test-page NAME\n            Select the named printer on start-up and print a\n            test page to it.\n\n  --no-focus-on-map\n            Do not focus the main window, to prevent focus \n            stealing\n\n  --debug   Enable debugging output.\n'
  38.  
  39. if len(sys.argv) > 1 and sys.argv[1] == '--help':
  40.     show_help()
  41.     sys.exit(0)
  42.  
  43. import cups
  44. cups.require('1.9.42')
  45.  
  46. try:
  47.     cups.ppdSetConformance(cups.PPD_CONFORM_RELAXED)
  48. except AttributeError:
  49.     pass
  50.  
  51.  
  52. try:
  53.     import pysmb
  54.     PYSMB_AVAILABLE = True
  55. except:
  56.     PYSMB_AVAILABLE = False
  57.  
  58. import cupshelpers
  59. import options
  60. import gobject
  61. from glade import GtkGUI
  62. from optionwidgets import OptionWidget
  63. from debug import *
  64. import probe_printer
  65. import gtk_label_autowrap
  66. import urllib
  67. import troubleshoot
  68. import jobviewer
  69. import authconn
  70. import monitor
  71. from smburi import SMBURI
  72. import errordialogs
  73. from errordialogs import *
  74. import installpackage
  75. import userdefault
  76. from AdvancedServerSettings import AdvancedServerSettingsDialog
  77. from PhysicalDevice import PhysicalDevice
  78. from ToolbarSearchEntry import *
  79. from GroupsPane import *
  80. from GroupsPaneModel import *
  81. from SearchCriterion import *
  82. import gtkinklevel
  83. import gtkspinner
  84. import statereason
  85. domain = 'system-config-printer'
  86. import locale
  87.  
  88. try:
  89.     locale.setlocale(locale.LC_ALL, '')
  90. except locale.Error:
  91.     os.environ['LC_ALL'] = 'C'
  92.     locale.setlocale(locale.LC_ALL, '')
  93.  
  94. from gettext import gettext as _
  95. monitor.set_gettext_function(_)
  96. errordialogs.set_gettext_function(_)
  97. authconn.set_gettext_function(_)
  98. import gettext
  99. gettext.textdomain(domain)
  100. gettext.bindtextdomain(domain, config.localedir)
  101. gtk.glade.textdomain(domain)
  102. gtk.glade.bindtextdomain(domain, config.localedir)
  103. import ppdippstr
  104. pkgdata = config.pkgdatadir
  105. iconpath = os.path.join(pkgdata, 'icons/')
  106. sys.path.append(pkgdata)
  107. busy_cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
  108. TEXT_start_firewall_tool = _('To do this, select System->Administration->Firewall from the main menu.')
  109.  
  110. try:
  111.     try_CUPS_SERVER_REMOTE_ANY = cups.CUPS_SERVER_REMOTE_ANY
  112. except AttributeError:
  113.     try_CUPS_SERVER_REMOTE_ANY = '_remote_any'
  114.  
  115.  
  116. def validDeviceURI(uri):
  117.     '''Returns True is the provided URI is valid.'''
  118.     (scheme, rest) = urllib.splittype(uri)
  119.     if scheme == None or scheme == '':
  120.         return False
  121.     return True
  122.  
  123.  
  124. def CUPS_server_hostname():
  125.     host = cups.getServer()
  126.     if host[0] == '/':
  127.         return 'localhost'
  128.     return host
  129.  
  130.  
  131. def moveClassMembers(treeview_from, treeview_to):
  132.     selection = treeview_from.get_selection()
  133.     (model_from, rows) = selection.get_selected_rows()
  134.     rows = [ gtk.TreeRowReference(model_from, row) for row in rows ]
  135.     model_to = treeview_to.get_model()
  136.     for row in rows:
  137.         path = row.get_path()
  138.         iter = model_from.get_iter(path)
  139.         row_data = model_from.get(iter, 0)
  140.         model_to.append(row_data)
  141.         model_from.remove(iter)
  142.     
  143.  
  144.  
  145. def getCurrentClassMembers(treeview):
  146.     model = treeview.get_model()
  147.     iter = model.get_iter_root()
  148.     result = []
  149.     while iter:
  150.         result.append(model.get(iter, 0)[0])
  151.         iter = model.iter_next(iter)
  152.     result.sort()
  153.     return result
  154.  
  155.  
  156. def on_delete_just_hide(widget, event):
  157.     widget.hide()
  158.     return True
  159.  
  160.  
  161. class GUI(GtkGUI, monitor.Watcher):
  162.     printer_states = {
  163.         cups.IPP_PRINTER_IDLE: _('Idle'),
  164.         cups.IPP_PRINTER_PROCESSING: _('Processing'),
  165.         cups.IPP_PRINTER_BUSY: _('Busy'),
  166.         cups.IPP_PRINTER_STOPPED: _('Stopped') }
  167.     
  168.     def __init__(self, setup_printer = None, configure_printer = None, change_ppd = False, devid = '', print_test_page = False, focus_on_map = True):
  169.         
  170.         try:
  171.             self.language = locale.getlocale(locale.LC_MESSAGES)
  172.             self.encoding = locale.getlocale(locale.LC_CTYPE)
  173.         except:
  174.             nonfatalException()
  175.             os.environ['LC_ALL'] = 'C'
  176.             locale.setlocale(locale.LC_ALL, '')
  177.             self.language = locale.getlocale(locale.LC_MESSAGES)
  178.             self.encoding = locale.getlocale(locale.LC_CTYPE)
  179.  
  180.         self.printer = None
  181.         self.conflicts = set()
  182.         if not self.printer or self.printer.getServer():
  183.             pass
  184.         self.connect_server = cups.getServer()
  185.         self.connect_encrypt = cups.getEncryption()
  186.         self.connect_user = cups.getUser()
  187.         self.changed = set()
  188.         self.servers = set((self.connect_server,))
  189.         self.server_is_publishing = False
  190.         self.devid = devid
  191.         self.focus_on_map = focus_on_map
  192.         self.updating_widgets = False
  193.         self.getWidgets({
  194.             'PrintersWindow': [
  195.                 'PrintersWindow',
  196.                 'view_area_vbox',
  197.                 'view_area_scrolledwindow',
  198.                 'dests_iconview',
  199.                 'statusbarMain',
  200.                 'toolbar',
  201.                 'server_settings_menu_entry',
  202.                 'new_printer',
  203.                 'new_class',
  204.                 'group_menubar_item',
  205.                 'printer_menubar_item',
  206.                 'view_discovered_printers',
  207.                 'view_groups'],
  208.             'AboutDialog': [
  209.                 'AboutDialog'],
  210.             'ConnectDialog': [
  211.                 'ConnectDialog',
  212.                 'chkEncrypted',
  213.                 'cmbServername',
  214.                 'btnConnect'],
  215.             'ConnectingDialog': [
  216.                 'ConnectingDialog',
  217.                 'lblConnecting',
  218.                 'pbarConnecting'],
  219.             'NewPrinterName': [
  220.                 'NewPrinterName',
  221.                 'entCopyName',
  222.                 'btnCopyOk'],
  223.             'ServerSettingsDialog': [
  224.                 'ServerSettingsDialog',
  225.                 'chkServerBrowse',
  226.                 'chkServerShare',
  227.                 'chkServerShareAny',
  228.                 'chkServerRemoteAdmin',
  229.                 'chkServerAllowCancelAll',
  230.                 'chkServerLogDebug',
  231.                 'hboxServerBrowse'],
  232.             'PrinterPropertiesDialog': [
  233.                 'PrinterPropertiesDialog',
  234.                 'tvPrinterProperties',
  235.                 'btnPrinterPropertiesCancel',
  236.                 'btnPrinterPropertiesOK',
  237.                 'btnPrinterPropertiesApply',
  238.                 'btnPrinterPropertiesClose',
  239.                 'ntbkPrinter',
  240.                 'entPDescription',
  241.                 'entPLocation',
  242.                 'lblPMakeModel',
  243.                 'lblPMakeModel2',
  244.                 'lblPState',
  245.                 'entPDevice',
  246.                 'lblPDevice2',
  247.                 'btnSelectDevice',
  248.                 'btnChangePPD',
  249.                 'chkPEnabled',
  250.                 'chkPAccepting',
  251.                 'chkPShared',
  252.                 'lblNotPublished',
  253.                 'btnPrintTestPage',
  254.                 'btnSelfTest',
  255.                 'btnCleanHeads',
  256.                 'btnConflict',
  257.                 'cmbPStartBanner',
  258.                 'cmbPEndBanner',
  259.                 'cmbPErrorPolicy',
  260.                 'cmbPOperationPolicy',
  261.                 'rbtnPAllow',
  262.                 'rbtnPDeny',
  263.                 'tvPUsers',
  264.                 'entPUser',
  265.                 'btnPAddUser',
  266.                 'btnPDelUser',
  267.                 'lblPInstallOptions',
  268.                 'swPInstallOptions',
  269.                 'vbPInstallOptions',
  270.                 'swPOptions',
  271.                 'lblPOptions',
  272.                 'vbPOptions',
  273.                 'algnClassMembers',
  274.                 'vbClassMembers',
  275.                 'lblClassMembers',
  276.                 'tvClassMembers',
  277.                 'tvClassNotMembers',
  278.                 'btnClassAddMember',
  279.                 'btnClassDelMember',
  280.                 'btnRefreshMarkerLevels',
  281.                 'tvPrinterStateReasons',
  282.                 'ntbkPrinterStateReasons',
  283.                 'sbJOCopies',
  284.                 'btnJOResetCopies',
  285.                 'cmbJOOrientationRequested',
  286.                 'btnJOResetOrientationRequested',
  287.                 'cbJOFitplot',
  288.                 'btnJOResetFitplot',
  289.                 'cmbJONumberUp',
  290.                 'btnJOResetNumberUp',
  291.                 'cmbJONumberUpLayout',
  292.                 'btnJOResetNumberUpLayout',
  293.                 'sbJOBrightness',
  294.                 'btnJOResetBrightness',
  295.                 'cmbJOFinishings',
  296.                 'btnJOResetFinishings',
  297.                 'sbJOJobPriority',
  298.                 'btnJOResetJobPriority',
  299.                 'cmbJOMedia',
  300.                 'btnJOResetMedia',
  301.                 'cmbJOSides',
  302.                 'btnJOResetSides',
  303.                 'cmbJOHoldUntil',
  304.                 'btnJOResetHoldUntil',
  305.                 'cbJOMirror',
  306.                 'btnJOResetMirror',
  307.                 'sbJOScaling',
  308.                 'btnJOResetScaling',
  309.                 'sbJOSaturation',
  310.                 'btnJOResetSaturation',
  311.                 'sbJOHue',
  312.                 'btnJOResetHue',
  313.                 'sbJOGamma',
  314.                 'btnJOResetGamma',
  315.                 'sbJOCpi',
  316.                 'btnJOResetCpi',
  317.                 'sbJOLpi',
  318.                 'btnJOResetLpi',
  319.                 'sbJOPageLeft',
  320.                 'btnJOResetPageLeft',
  321.                 'sbJOPageRight',
  322.                 'btnJOResetPageRight',
  323.                 'sbJOPageTop',
  324.                 'btnJOResetPageTop',
  325.                 'sbJOPageBottom',
  326.                 'btnJOResetPageBottom',
  327.                 'cbJOPrettyPrint',
  328.                 'btnJOResetPrettyPrint',
  329.                 'cbJOWrap',
  330.                 'btnJOResetWrap',
  331.                 'sbJOColumns',
  332.                 'btnJOResetColumns',
  333.                 'tblJOOther',
  334.                 'entNewJobOption',
  335.                 'btnNewJobOption',
  336.                 'vboxMarkerLevels',
  337.                 'btnRefreshMarkerLevels'] })
  338.         self.PrintersWindow.set_focus_on_map(self.focus_on_map)
  339.         for dialog in [
  340.             self.PrinterPropertiesDialog,
  341.             self.ServerSettingsDialog]:
  342.             dialog.connect('delete-event', on_delete_just_hide)
  343.         
  344.         self.ConnectingDialog.connect('delete-event', self.on_connectingdialog_delete)
  345.         gtk.window_set_default_icon_name('printer')
  346.         self.btnNew = gtk.MenuToolButton('gtk-new')
  347.         self.btnNew.set_is_important(True)
  348.         newmenu = gtk.Menu()
  349.         newprinter = gtk.ImageMenuItem(_('Printer'))
  350.         printericon = gtk.Image()
  351.         printericon.set_from_icon_name('printer', gtk.ICON_SIZE_MENU)
  352.         newprinter.set_image(printericon)
  353.         newprinter.connect('activate', self.on_new_printer_activate)
  354.         self.btnNew.connect('clicked', self.on_new_printer_activate)
  355.         newclass = gtk.ImageMenuItem(_('Class'))
  356.         classicon = gtk.Image()
  357.         classicon.set_from_icon_name('gtk-dnd-multiple', gtk.ICON_SIZE_MENU)
  358.         newclass.set_image(classicon)
  359.         newclass.connect('activate', self.on_new_class_activate)
  360.         newprinter.show()
  361.         newclass.show()
  362.         newmenu.attach(newprinter, 0, 1, 0, 1)
  363.         newmenu.attach(newclass, 0, 1, 1, 2)
  364.         self.btnNew.set_menu(newmenu)
  365.         self.toolbar.add(self.btnNew)
  366.         self.toolbar.add(gtk.SeparatorToolItem())
  367.         refreshbutton = gtk.ToolButton('gtk-refresh')
  368.         refreshbutton.connect('clicked', self.on_btnRefresh_clicked)
  369.         self.toolbar.add(refreshbutton)
  370.         self.toolbar.show_all()
  371.         printer_manager_action_group = gtk.ActionGroup('PrinterManagerActionGroup')
  372.         printer_manager_action_group.add_actions([
  373.             ('rename-printer', None, _('_Rename'), None, None, self.on_rename_activate),
  374.             ('copy-printer', gtk.STOCK_COPY, None, '<Ctrl>c', None, self.on_copy_activate),
  375.             ('delete-printer', gtk.STOCK_DELETE, None, None, None, self.on_delete_activate),
  376.             ('set-default-printer', gtk.STOCK_HOME, _('Set As De_fault'), None, None, self.on_set_as_default_activate),
  377.             ('edit-printer', gtk.STOCK_PROPERTIES, None, None, None, self.on_edit_activate),
  378.             ('create-class', gtk.STOCK_DND_MULTIPLE, _('_Create class'), None, None, self.on_create_class_activate),
  379.             ('view-print-queue', gtk.STOCK_FIND, _('View Print _Queue'), None, None, self.on_view_print_queue_activate),
  380.             ('add-to-group', None, _('_Add to Group'), None, None, None),
  381.             ('save-as-group', None, _('Save Results as _Group'), None, None, self.on_save_as_group_activate),
  382.             ('save-as-search-group', None, _('Save Filter as _Search Group'), None, None, self.on_save_as_search_group_activate)])
  383.         printer_manager_action_group.add_toggle_actions([
  384.             ('enable-printer', None, _('E_nabled'), None, None, self.on_enabled_activate),
  385.             ('share-printer', None, _('_Shared'), None, None, self.on_shared_activate)])
  386.         printer_manager_action_group.add_radio_actions([
  387.             ('filter-name', None, _('Name')),
  388.             ('filter-description', None, _('Description')),
  389.             ('filter-location', None, _('Location')),
  390.             ('filter-manufacturer', None, _('Manufacturer / Model'))], 1, self.on_filter_criterion_changed)
  391.         for action in printer_manager_action_group.list_actions():
  392.             action.set_sensitive(False)
  393.         
  394.         printer_manager_action_group.get_action('view-print-queue').set_sensitive(True)
  395.         printer_manager_action_group.get_action('filter-name').set_sensitive(True)
  396.         printer_manager_action_group.get_action('filter-description').set_sensitive(True)
  397.         printer_manager_action_group.get_action('filter-location').set_sensitive(True)
  398.         printer_manager_action_group.get_action('filter-manufacturer').set_sensitive(True)
  399.         self.ui_manager = gtk.UIManager()
  400.         self.ui_manager.insert_action_group(printer_manager_action_group, -1)
  401.         self.ui_manager.add_ui_from_string('\n<ui>\n <accelerator action="rename-printer"/>\n <accelerator action="copy-printer"/>\n <accelerator action="delete-printer"/>\n <accelerator action="set-default-printer"/>\n <accelerator action="edit-printer"/>\n <accelerator action="create-class"/>\n <accelerator action="view-print-queue"/>\n <accelerator action="add-to-group"/>\n <accelerator action="save-as-group"/>\n <accelerator action="save-as-search-group"/>\n <accelerator action="enable-printer"/>\n <accelerator action="share-printer"/>\n <accelerator action="filter-name"/>\n <accelerator action="filter-description"/>\n <accelerator action="filter-location"/>\n <accelerator action="filter-manufacturer"/>\n</ui>\n')
  402.         self.ui_manager.ensure_update()
  403.         self.PrintersWindow.add_accel_group(self.ui_manager.get_accel_group())
  404.         self.printer_context_menu = gtk.Menu()
  405.         for action_name in [
  406.             'edit-printer',
  407.             'copy-printer',
  408.             'rename-printer',
  409.             'delete-printer',
  410.             None,
  411.             'enable-printer',
  412.             'share-printer',
  413.             'create-class',
  414.             'set-default-printer',
  415.             None,
  416.             'add-to-group',
  417.             'view-print-queue']:
  418.             if not action_name:
  419.                 item = gtk.SeparatorMenuItem()
  420.             else:
  421.                 action = printer_manager_action_group.get_action(action_name)
  422.                 item = action.create_menu_item()
  423.             item.show()
  424.             self.printer_context_menu.append(item)
  425.         
  426.         self.printer_menubar_item.set_submenu(self.printer_context_menu)
  427.         self.jobviewers = []
  428.         for combobox in [
  429.             self.cmbPStartBanner,
  430.             self.cmbPEndBanner,
  431.             self.cmbPErrorPolicy,
  432.             self.cmbPOperationPolicy]:
  433.             cell = gtk.CellRendererText()
  434.             combobox.clear()
  435.             combobox.pack_start(cell, True)
  436.             combobox.add_attribute(cell, 'text', 0)
  437.         
  438.         btn = self.btnRefreshMarkerLevels
  439.         btn.connect('clicked', self.on_btnRefreshMarkerLevels_clicked)
  440.         column = gtk.TreeViewColumn(_('Message'))
  441.         icon = gtk.CellRendererPixbuf()
  442.         column.pack_start(icon, False)
  443.         text = gtk.CellRendererText()
  444.         column.pack_start(text, False)
  445.         column.set_cell_data_func(icon, self.set_printer_state_reason_icon)
  446.         column.set_cell_data_func(text, self.set_printer_state_reason_text)
  447.         column.set_resizable(True)
  448.         self.tvPrinterStateReasons.append_column(column)
  449.         selection = self.tvPrinterStateReasons.get_selection()
  450.         selection.set_mode(gtk.SELECTION_NONE)
  451.         store = gtk.ListStore(int, str)
  452.         self.tvPrinterStateReasons.set_model(store)
  453.         self.newPrinterGUI = np = NewPrinterGUI(self)
  454.         np.NewPrinterWindow.set_transient_for(self.PrintersWindow)
  455.         self.AboutDialog.set_program_name(domain)
  456.         self.AboutDialog.set_version(config.VERSION)
  457.         self.AboutDialog.set_icon_name('printer')
  458.         
  459.         class UnobtrusiveButton(gtk.Button):
  460.             
  461.             def __init__(self, **args):
  462.                 gtk.Button.__init__(self, **args)
  463.                 self.set_relief(gtk.RELIEF_NONE)
  464.                 label = self.get_child()
  465.                 text = label.get_text()
  466.                 label.set_use_markup(True)
  467.                 label.set_markup('<span size="small" ' + 'underline="single" ' + 'color="#0000ee">%s</span>' % text)
  468.  
  469.  
  470.         problems = UnobtrusiveButton(label = _('Problems?'))
  471.         self.hboxServerBrowse.pack_end(problems, False, False, 0)
  472.         problems.connect('clicked', self.on_problems_button_clicked)
  473.         problems.show()
  474.         self.static_tabs = 3
  475.         gtk_label_autowrap.set_autowrap(self.PrintersWindow)
  476.         
  477.         try:
  478.             self.cups = authconn.Connection(self.PrintersWindow)
  479.         except RuntimeError:
  480.             self.cups = None
  481.  
  482.         self.status_context_id = self.statusbarMain.get_context_id('Connection')
  483.         self.setConnected()
  484.         self.setup_toolbar_for_search_entry()
  485.         self.current_filter_text = ''
  486.         self.current_filter_mode = 'filter-name'
  487.         self.groups_pane = GroupsPane()
  488.         self.current_groups_pane_item = self.groups_pane.get_selected_item()
  489.         self.groups_pane.connect('item-activated', self.on_groups_pane_item_activated)
  490.         self.groups_pane.connect('items-changed', self.on_groups_pane_items_changed)
  491.         self.PrintersWindow.add_accel_group(self.groups_pane.ui_manager.get_accel_group())
  492.         self.view_area_hpaned = gtk.HPaned()
  493.         self.view_area_hpaned.add1(self.groups_pane)
  494.         self.groups_pane_visible = False
  495.         if self.groups_pane.n_groups() > 0:
  496.             self.view_groups.set_active(True)
  497.         
  498.         self.group_menubar_item.set_submenu(self.groups_pane.groups_menu)
  499.         self.add_to_group_menu = gtk.Menu()
  500.         self.update_add_to_group_menu()
  501.         action = printer_manager_action_group.get_action('add-to-group')
  502.         for proxy in action.get_proxies():
  503.             if isinstance(proxy, gtk.MenuItem):
  504.                 item = proxy
  505.                 break
  506.                 continue
  507.         
  508.         item.set_submenu(self.add_to_group_menu)
  509.         menu = gtk.Menu()
  510.         for action_name in [
  511.             'filter-name',
  512.             'filter-description',
  513.             'filter-location',
  514.             'filter-manufacturer',
  515.             None,
  516.             'save-as-group',
  517.             'save-as-search-group']:
  518.             if not action_name:
  519.                 item = gtk.SeparatorMenuItem()
  520.             else:
  521.                 action = printer_manager_action_group.get_action(action_name)
  522.                 item = action.create_menu_item()
  523.             menu.append(item)
  524.         
  525.         menu.show_all()
  526.         self.search_entry.set_drop_down_menu(menu)
  527.         self.mainlist = gtk.ListStore(gobject.TYPE_PYOBJECT, gtk.gdk.Pixbuf, gobject.TYPE_STRING, gobject.TYPE_STRING)
  528.         self.dests_iconview.set_model(self.mainlist)
  529.         self.dests_iconview.set_column_spacing(30)
  530.         self.dests_iconview.set_row_spacing(20)
  531.         self.dests_iconview.set_pixbuf_column(1)
  532.         self.dests_iconview.set_text_column(2)
  533.         self.dests_iconview.set_tooltip_column(3)
  534.         self.dests_iconview.set_has_tooltip(True)
  535.         self.dests_iconview.connect('key-press-event', self.dests_iconview_key_press_event)
  536.         self.dests_iconview.connect('item-activated', self.dests_iconview_item_activated)
  537.         self.dests_iconview.connect('selection-changed', self.dests_iconview_selection_changed)
  538.         self.dests_iconview.connect('button-press-event', self.dests_iconview_button_press_event)
  539.         self.dests_iconview.connect('popup-menu', self.dests_iconview_popup_menu)
  540.         self.dests_iconview_selection_changed(self.dests_iconview)
  541.         self.dests_iconview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [
  542.             ('queue', 0, 0)], gtk.gdk.ACTION_COPY)
  543.         self.dests_iconview.connect('drag-data-get', self.dests_iconview_drag_data_get)
  544.         m = gtk.SELECTION_MULTIPLE
  545.         s = gtk.SELECTION_SINGLE
  546.         for name, treeview, selection_mode in ((_('Members of this class'), self.tvClassMembers, m), (_('Others'), self.tvClassNotMembers, m), (_('Members of this class'), np.tvNCMembers, m), (_('Others'), np.tvNCNotMembers, m), (_('Devices'), np.tvNPDevices, s), (_('Connections'), np.tvNPDeviceURIs, s), (_('Makes'), np.tvNPMakes, s), (_('Models'), np.tvNPModels, s), (_('Drivers'), np.tvNPDrivers, s), (_('Downloadable Drivers'), np.tvNPDownloadableDrivers, s), (_('Users'), self.tvPUsers, m)):
  547.             model = gtk.ListStore(str)
  548.             cell = gtk.CellRendererText()
  549.             column = gtk.TreeViewColumn(name, cell, text = 0)
  550.             treeview.set_model(model)
  551.             treeview.append_column(column)
  552.             treeview.get_selection().set_mode(selection_mode)
  553.         
  554.         self.ServerSettingsDialog.connect('response', self.server_settings_response)
  555.         self.PrinterPropertiesDialog.connect('response', self.printer_properties_response)
  556.         col = gtk.TreeViewColumn('', gtk.CellRendererText(), markup = 0)
  557.         self.tvPrinterProperties.append_column(col)
  558.         sel = self.tvPrinterProperties.get_selection()
  559.         sel.connect('changed', self.on_tvPrinterProperties_selection_changed)
  560.         sel.set_mode(gtk.SELECTION_SINGLE)
  561.         opts = [
  562.             options.OptionAlwaysShown('copies', int, 1, self.sbJOCopies, self.btnJOResetCopies),
  563.             options.OptionAlwaysShownSpecial('orientation-requested', int, 3, self.cmbJOOrientationRequested, self.btnJOResetOrientationRequested, combobox_map = [
  564.                 3,
  565.                 4,
  566.                 5,
  567.                 6], special_choice = _('Automatic rotation')),
  568.             options.OptionAlwaysShown('fitplot', bool, False, self.cbJOFitplot, self.btnJOResetFitplot),
  569.             options.OptionAlwaysShown('number-up', int, 1, self.cmbJONumberUp, self.btnJOResetNumberUp, combobox_map = [
  570.                 1,
  571.                 2,
  572.                 4,
  573.                 6,
  574.                 9,
  575.                 16]),
  576.             options.OptionAlwaysShown('number-up-layout', str, 'lrtb', self.cmbJONumberUpLayout, self.btnJOResetNumberUpLayout, combobox_map = [
  577.                 'lrtb',
  578.                 'lrbt',
  579.                 'rltb',
  580.                 'rlbt',
  581.                 'tblr',
  582.                 'tbrl',
  583.                 'btlr',
  584.                 'btrl']),
  585.             options.OptionAlwaysShown('brightness', int, 100, self.sbJOBrightness, self.btnJOResetBrightness),
  586.             options.OptionAlwaysShown('finishings', int, 3, self.cmbJOFinishings, self.btnJOResetFinishings, combobox_map = [
  587.                 3,
  588.                 4,
  589.                 5,
  590.                 6,
  591.                 7,
  592.                 8,
  593.                 9,
  594.                 10,
  595.                 11,
  596.                 12,
  597.                 13,
  598.                 14,
  599.                 20,
  600.                 21,
  601.                 22,
  602.                 23,
  603.                 24,
  604.                 25,
  605.                 26,
  606.                 27,
  607.                 28,
  608.                 29,
  609.                 30,
  610.                 31,
  611.                 50,
  612.                 51,
  613.                 52,
  614.                 53], use_supported = True),
  615.             options.OptionAlwaysShown('job-priority', int, 50, self.sbJOJobPriority, self.btnJOResetJobPriority),
  616.             options.OptionAlwaysShown('media', str, 'A4', self.cmbJOMedia, self.btnJOResetMedia, use_supported = True),
  617.             options.OptionAlwaysShown('sides', str, 'one-sided', self.cmbJOSides, self.btnJOResetSides, combobox_map = [
  618.                 'one-sided',
  619.                 'two-sided-long-edge',
  620.                 'two-sided-short-edge']),
  621.             options.OptionAlwaysShown('job-hold-until', str, 'no-hold', self.cmbJOHoldUntil, self.btnJOResetHoldUntil, use_supported = True),
  622.             options.OptionAlwaysShown('mirror', bool, False, self.cbJOMirror, self.btnJOResetMirror),
  623.             options.OptionAlwaysShown('scaling', int, 100, self.sbJOScaling, self.btnJOResetScaling),
  624.             options.OptionAlwaysShown('saturation', int, 100, self.sbJOSaturation, self.btnJOResetSaturation),
  625.             options.OptionAlwaysShown('hue', int, 0, self.sbJOHue, self.btnJOResetHue),
  626.             options.OptionAlwaysShown('gamma', int, 1000, self.sbJOGamma, self.btnJOResetGamma),
  627.             options.OptionAlwaysShown('cpi', float, 10, self.sbJOCpi, self.btnJOResetCpi),
  628.             options.OptionAlwaysShown('lpi', float, 6, self.sbJOLpi, self.btnJOResetLpi),
  629.             options.OptionAlwaysShown('page-left', int, 0, self.sbJOPageLeft, self.btnJOResetPageLeft),
  630.             options.OptionAlwaysShown('page-right', int, 0, self.sbJOPageRight, self.btnJOResetPageRight),
  631.             options.OptionAlwaysShown('page-top', int, 0, self.sbJOPageTop, self.btnJOResetPageTop),
  632.             options.OptionAlwaysShown('page-bottom', int, 0, self.sbJOPageBottom, self.btnJOResetPageBottom),
  633.             options.OptionAlwaysShown('prettyprint', bool, False, self.cbJOPrettyPrint, self.btnJOResetPrettyPrint),
  634.             options.OptionAlwaysShown('wrap', bool, False, self.cbJOWrap, self.btnJOResetWrap),
  635.             options.OptionAlwaysShown('columns', int, 1, self.sbJOColumns, self.btnJOResetColumns)]
  636.         self.job_options_widgets = { }
  637.         self.job_options_buttons = { }
  638.         for option in opts:
  639.             self.job_options_widgets[option.widget] = option
  640.             self.job_options_buttons[option.button] = option
  641.         
  642.         self.monitor = monitor.Monitor(self, monitor_jobs = False)
  643.         
  644.         try:
  645.             self.populateList()
  646.         except cups.HTTPError:
  647.             (s,) = None
  648.             self.cups = None
  649.             self.setConnected()
  650.             self.populateList()
  651.             show_HTTP_Error(s, self.PrintersWindow)
  652.  
  653.         if len(self.printers) > 3:
  654.             self.PrintersWindow.set_default_size(550, 400)
  655.         
  656.         self.PrintersWindow.show()
  657.         if setup_printer:
  658.             self.device_uri = setup_printer
  659.             self.devid = devid
  660.             self.ppd = None
  661.             
  662.             try:
  663.                 self.on_autodetected_printer_without_driver(None)
  664.             except RuntimeError:
  665.                 pass
  666.             except:
  667.                 None<EXCEPTION MATCH>RuntimeError
  668.             
  669.  
  670.         None<EXCEPTION MATCH>RuntimeError
  671.         if configure_printer:
  672.             
  673.             try:
  674.                 self.display_properties_dialog_for(configure_printer)
  675.                 if print_test_page:
  676.                     self.btnPrintTestPage.clicked()
  677.                 
  678.                 if change_ppd:
  679.                     self.btnChangePPD.clicked()
  680.             except RuntimeError:
  681.                 pass
  682.             except:
  683.                 None<EXCEPTION MATCH>RuntimeError
  684.             
  685.  
  686.         None<EXCEPTION MATCH>RuntimeError
  687.  
  688.     
  689.     def display_properties_dialog_for(self, queue):
  690.         model = self.dests_iconview.get_model()
  691.         iter = model.get_iter_first()
  692.         while iter != None:
  693.             name = unicode(model.get_value(iter, 2))
  694.             if name == queue:
  695.                 path = model.get_path(iter)
  696.                 self.dests_iconview.scroll_to_path(path, True, 0.5, 0.5)
  697.                 self.dests_iconview.set_cursor(path)
  698.                 self.dests_iconview.item_activated(path)
  699.                 break
  700.             
  701.             iter = model.iter_next(iter)
  702.         if iter == None:
  703.             raise RuntimeError
  704.         iter == None
  705.  
  706.     
  707.     def setup_toolbar_for_search_entry(self):
  708.         separator = gtk.SeparatorToolItem()
  709.         separator.set_draw(False)
  710.         self.toolbar.insert(separator, -1)
  711.         self.toolbar.child_set_property(separator, 'expand', True)
  712.         self.search_entry = ToolbarSearchEntry()
  713.         self.search_entry.connect('search', self.on_search_entry_search)
  714.         tool_item = gtk.ToolItem()
  715.         tool_item.add(self.search_entry)
  716.         self.toolbar.insert(tool_item, -1)
  717.         self.toolbar.show_all()
  718.  
  719.     
  720.     def on_search_entry_search(self, UNUSED, text):
  721.         if not text or True:
  722.             pass
  723.         self.ui_manager.get_action('/save-as-group').set_sensitive(False)
  724.         if not text or True:
  725.             pass
  726.         self.ui_manager.get_action('/save-as-search-group').set_sensitive(False)
  727.         self.current_filter_text = text
  728.         self.populateList()
  729.  
  730.     
  731.     def on_groups_pane_item_activated(self, UNUSED, item):
  732.         self.search_entry.clear()
  733.         if isinstance(item, SavedSearchGroupItem):
  734.             crit = item.criteria[0]
  735.             if crit.subject == SearchCriterion.SUBJECT_NAME:
  736.                 self.ui_manager.get_action('/filter-name').activate()
  737.             elif crit.subject == SearchCriterion.SUBJECT_DESC:
  738.                 self.ui_manager.get_action('/filter-description').activate()
  739.             elif crit.subject == SearchCriterion.SUBJECT_LOCATION:
  740.                 self.ui_manager.get_action('/filter-location').activate()
  741.             elif crit.subject == SearchCriterion.SUBJECT_MANUF:
  742.                 self.ui_manager.get_action('/filter-manufacturer').activate()
  743.             else:
  744.                 nonfatalException()
  745.             self.search_entry.set_text(crit.value)
  746.         
  747.         self.current_groups_pane_item = item
  748.         self.populateList()
  749.  
  750.     
  751.     def on_add_to_group_menu_item_activate(self, menuitem, group):
  752.         group.add_queues(self.groups_pane.currently_selected_queues)
  753.  
  754.     
  755.     def update_add_to_group_menu(self):
  756.         for child in self.add_to_group_menu.get_children():
  757.             self.add_to_group_menu.remove(child)
  758.         
  759.         static_groups = self.groups_pane.get_static_groups()
  760.         for group in static_groups:
  761.             item = gtk.MenuItem(group.name, False)
  762.             item.connect('activate', self.on_add_to_group_menu_item_activate, group)
  763.             self.add_to_group_menu.append(item)
  764.         
  765.         if len(static_groups) > 0:
  766.             item = gtk.SeparatorMenuItem()
  767.             self.add_to_group_menu.append(item)
  768.         
  769.         action = self.groups_pane.ui_manager.get_action('/new-group-from-selection')
  770.         item = action.create_menu_item()
  771.         self.add_to_group_menu.append(item)
  772.         self.add_to_group_menu.show_all()
  773.  
  774.     
  775.     def on_groups_pane_items_changed(self, UNUSED):
  776.         if not self.groups_pane_visible:
  777.             self.view_groups.set_active(True)
  778.         
  779.         self.update_add_to_group_menu()
  780.  
  781.     
  782.     def on_filter_criterion_changed(self, UNUSED, selected_action):
  783.         self.current_filter_mode = selected_action.get_name()
  784.         self.populateList()
  785.  
  786.     
  787.     def dests_iconview_item_activated(self, iconview, path):
  788.         model = iconview.get_model()
  789.         iter = model.get_iter(path)
  790.         name = unicode(model.get_value(iter, 2))
  791.         object = model.get_value(iter, 0)
  792.         
  793.         try:
  794.             self.fillPrinterTab(name)
  795.         except cups.IPPError:
  796.             (e, m) = None
  797.             show_IPP_Error(e, m, self.PrintersWindow)
  798.             if e == cups.IPP_SERVICE_UNAVAILABLE:
  799.                 self.cups = None
  800.                 self.setConnected()
  801.                 self.populateList()
  802.             
  803.             return None
  804.             except RuntimeError:
  805.                 return None
  806.             else:
  807.                 self.PrinterPropertiesDialog.set_transient_for(self.PrintersWindow)
  808.                 for button in [
  809.                     self.btnPrinterPropertiesCancel,
  810.                     self.btnPrinterPropertiesOK,
  811.                     self.btnPrinterPropertiesApply]:
  812.                     if object.discovered:
  813.                         button.hide()
  814.                         continue
  815.                     button.show()
  816.                 
  817.  
  818.         if object.discovered:
  819.             self.btnPrinterPropertiesClose.show()
  820.         else:
  821.             self.btnPrinterPropertiesClose.hide()
  822.         self.setDataButtonState()
  823.         treeview = self.tvPrinterProperties
  824.         treeview.set_cursor((0,))
  825.         host = CUPS_server_hostname()
  826.         self.PrinterPropertiesDialog.set_title(_("Printer Properties - '%s' on %s") % (name, host))
  827.         self.PrinterPropertiesDialog.set_focus_on_map(self.focus_on_map)
  828.         self.PrinterPropertiesDialog.show()
  829.  
  830.     
  831.     def printer_properties_response(self, dialog, response):
  832.         if response == gtk.RESPONSE_REJECT:
  833.             message = _('There are conflicting options.\nChanges can only be applied after\nthese conflicts are resolved.')
  834.             message += '\n\n'
  835.             for option in self.conflicts:
  836.                 message += option.option.text + '\n'
  837.             
  838.             dialog = gtk.MessageDialog(self.PrinterPropertiesDialog, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE, message)
  839.             dialog.run()
  840.             dialog.destroy()
  841.             return None
  842.         if response == gtk.RESPONSE_OK or response == gtk.RESPONSE_APPLY:
  843.             success = self.save_printer(self.printer)
  844.         
  845.         if response == gtk.RESPONSE_APPLY:
  846.             
  847.             try:
  848.                 self.fillPrinterTab(self.printer.name)
  849.             except:
  850.                 pass
  851.  
  852.             self.setDataButtonState()
  853.         
  854.         if response == gtk.RESPONSE_OK or not success or response == gtk.RESPONSE_CANCEL:
  855.             self.printer = None
  856.             dialog.hide()
  857.         
  858.  
  859.     
  860.     def dests_iconview_selection_changed(self, iconview):
  861.         self.updating_widgets = True
  862.         paths = iconview.get_selected_items()
  863.         any_disabled = False
  864.         any_enabled = False
  865.         any_discovered = False
  866.         any_shared = False
  867.         any_unshared = False
  868.         self.groups_pane.currently_selected_queues = []
  869.         model = iconview.get_model()
  870.         for path in paths:
  871.             iter = model.get_iter(path)
  872.             object = model.get_value(iter, 0)
  873.             name = unicode(model.get_value(iter, 2))
  874.             self.groups_pane.currently_selected_queues.append(name)
  875.             if object.discovered:
  876.                 any_discovered = True
  877.             
  878.             if object.enabled:
  879.                 any_enabled = True
  880.             else:
  881.                 any_disabled = True
  882.             if object.is_shared:
  883.                 any_shared = True
  884.                 continue
  885.             any_unshared = True
  886.         
  887.         n = len(paths)
  888.         self.groups_pane.ui_manager.get_action('/new-group-from-selection').set_sensitive(n > 0)
  889.         self.ui_manager.get_action('/edit-printer').set_sensitive(n == 1)
  890.         self.ui_manager.get_action('/copy-printer').set_sensitive(n == 1)
  891.         if n == 1:
  892.             pass
  893.         self.ui_manager.get_action('/rename-printer').set_sensitive(not any_discovered)
  894.         userdef = userdefault.UserDefaultPrinter().get()
  895.         if (n != 1 or userdef == None) and self.default_printer == name:
  896.             set_default_sensitivity = False
  897.         else:
  898.             set_default_sensitivity = True
  899.         self.ui_manager.get_action('/set-default-printer').set_sensitive(set_default_sensitivity)
  900.         action = self.ui_manager.get_action('/enable-printer')
  901.         if n > 0:
  902.             pass
  903.         action.set_sensitive(not any_discovered)
  904.         for widget in action.get_proxies():
  905.             if isinstance(widget, gtk.CheckMenuItem):
  906.                 if n > 1 and any_enabled:
  907.                     pass
  908.                 widget.set_inconsistent(any_disabled)
  909.                 continue
  910.         
  911.         if not any_discovered:
  912.             pass
  913.         action.set_active(not any_disabled)
  914.         action = self.ui_manager.get_action('/share-printer')
  915.         if n > 0:
  916.             pass
  917.         action.set_sensitive(not any_discovered)
  918.         for widget in action.get_proxies():
  919.             if isinstance(widget, gtk.CheckMenuItem):
  920.                 if n > 1 and any_shared:
  921.                     pass
  922.                 widget.set_inconsistent(any_unshared)
  923.                 continue
  924.         
  925.         if not any_discovered:
  926.             pass
  927.         action.set_active(not any_unshared)
  928.         if n > 0:
  929.             pass
  930.         self.ui_manager.get_action('/delete-printer').set_sensitive(not any_discovered)
  931.         self.ui_manager.get_action('/create-class').set_sensitive(n > 1)
  932.         self.ui_manager.get_action('/add-to-group').set_sensitive(n > 0)
  933.         self.updating_widgets = False
  934.  
  935.     
  936.     def dests_iconview_popup_menu(self, iconview):
  937.         self.printer_context_menu.popup(None, None, None, 0, 0x0L)
  938.  
  939.     
  940.     def dests_iconview_button_press_event(self, iconview, event):
  941.         if event.button > 1:
  942.             click_path = iconview.get_path_at_pos(int(event.x), int(event.y))
  943.             paths = iconview.get_selected_items()
  944.             if click_path == None:
  945.                 iconview.unselect_all()
  946.             elif click_path not in paths:
  947.                 iconview.unselect_all()
  948.                 iconview.select_path(click_path)
  949.                 cells = iconview.get_cells()
  950.                 for cell in cells:
  951.                     if type(cell) == gtk.CellRendererText:
  952.                         break
  953.                         continue
  954.                 
  955.                 iconview.set_cursor(click_path, cell)
  956.             
  957.             self.printer_context_menu.popup(None, None, None, event.button, event.time)
  958.         
  959.         return False
  960.  
  961.     
  962.     def dests_iconview_key_press_event(self, iconview, event):
  963.         modifiers = gtk.accelerator_get_default_mod_mask()
  964.         if (event.keyval == gtk.keysyms.BackSpace and event.keyval == gtk.keysyms.Delete or event.keyval == gtk.keysyms.KP_Delete) and event.state & modifiers == 0:
  965.             self.ui_manager.get_action('/delete-printer').activate()
  966.             return True
  967.         if event.keyval == gtk.keysyms.F2 and event.state & modifiers == 0:
  968.             self.ui_manager.get_action('/rename-printer').activate()
  969.             return True
  970.         return False
  971.  
  972.     
  973.     def dests_iconview_drag_data_get(self, iconview, context, selection_data, info, timestamp):
  974.         if info == 0:
  975.             model = iconview.get_model()
  976.             paths = iconview.get_selected_items()
  977.             selected_printer_names = ''
  978.             for path in paths:
  979.                 selected_printer_names += model.get_value(model.get_iter(path), 2) + '\n'
  980.             
  981.             if len(selected_printer_names) > 0:
  982.                 selection_data.set('queue', 8, selected_printer_names)
  983.             
  984.         else:
  985.             nonfatalException()
  986.  
  987.     
  988.     def on_server_settings_activate(self, menuitem):
  989.         
  990.         try:
  991.             self.fillServerTab()
  992.         except cups.IPPError:
  993.             return None
  994.  
  995.         self.ServerSettingsDialog.set_transient_for(self.PrintersWindow)
  996.         self.ServerSettingsDialog.show()
  997.  
  998.     
  999.     def server_settings_response(self, dialog, response):
  1000.         if response == gtk.RESPONSE_OK:
  1001.             if not self.save_serversettings():
  1002.                 dialog.hide()
  1003.             
  1004.         elif response == gtk.RESPONSE_YES:
  1005.             
  1006.             try:
  1007.                 AdvancedServerSettingsDialog(self.cups, dialog, self.on_adv_server_settings_apply)
  1008.             return None
  1009.  
  1010.         else:
  1011.             dialog.hide()
  1012.  
  1013.     
  1014.     def on_adv_server_settings_apply(self):
  1015.         
  1016.         try:
  1017.             self.fillServerTab()
  1018.         except cups.IPPError:
  1019.             self.ServerSettingsDialog.hide()
  1020.  
  1021.  
  1022.     
  1023.     def busy(self, win = None):
  1024.         
  1025.         try:
  1026.             if not win:
  1027.                 win = self.PrintersWindow
  1028.             
  1029.             gdkwin = win.window
  1030.             if gdkwin:
  1031.                 gdkwin.set_cursor(busy_cursor)
  1032.                 while gtk.events_pending():
  1033.                     gtk.main_iteration()
  1034.         except:
  1035.             nonfatalException()
  1036.  
  1037.  
  1038.     
  1039.     def ready(self, win = None):
  1040.         
  1041.         try:
  1042.             if not win:
  1043.                 win = self.PrintersWindow
  1044.             
  1045.             gdkwin = win.window
  1046.             if gdkwin:
  1047.                 gdkwin.set_cursor(None)
  1048.                 while gtk.events_pending():
  1049.                     gtk.main_iteration()
  1050.         except:
  1051.             nonfatalException()
  1052.  
  1053.  
  1054.     
  1055.     def setConnected(self):
  1056.         connected = bool(self.cups)
  1057.         host = CUPS_server_hostname()
  1058.         self.PrintersWindow.set_title(_('Printer configuration - %s') % host)
  1059.         self.PrintersWindow.set_focus_on_map(self.focus_on_map)
  1060.         if connected:
  1061.             status_msg = _('Connected to %s') % host
  1062.         else:
  1063.             status_msg = _('Not connected')
  1064.         self.statusbarMain.push(self.status_context_id, status_msg)
  1065.         for widget in (self.btnNew, self.new_printer, self.new_class, self.chkServerBrowse, self.chkServerShare, self.chkServerRemoteAdmin, self.chkServerAllowCancelAll, self.chkServerLogDebug, self.server_settings_menu_entry):
  1066.             widget.set_sensitive(connected)
  1067.         
  1068.         sharing = self.chkServerShare.get_active()
  1069.         self.chkServerShareAny.set_sensitive(sharing)
  1070.         
  1071.         try:
  1072.             del self.server_settings
  1073.         except:
  1074.             pass
  1075.  
  1076.  
  1077.     
  1078.     def getServers(self):
  1079.         self.servers.discard(None)
  1080.         known_servers = list(self.servers)
  1081.         known_servers.sort()
  1082.         return known_servers
  1083.  
  1084.     
  1085.     def populateList(self, prompt_allowed = True):
  1086.         selected_printers = set()
  1087.         paths = self.dests_iconview.get_selected_items()
  1088.         model = self.dests_iconview.get_model()
  1089.         for path in paths:
  1090.             iter = model.get_iter(path)
  1091.             name = unicode(model.get_value(iter, 2))
  1092.             selected_printers.add(name)
  1093.         
  1094.         if self.cups:
  1095.             self.cups._set_prompt_allowed(prompt_allowed)
  1096.             self.cups._begin_operation(_('obtaining queue details'))
  1097.             
  1098.             try:
  1099.                 self.printers = cupshelpers.getPrinters(self.cups)
  1100.                 self.default_printer = self.cups.getDefault()
  1101.             except cups.IPPError:
  1102.                 (e, m) = None
  1103.                 show_IPP_Error(e, m, self.PrintersWindow)
  1104.                 self.printers = { }
  1105.                 self.default_printer = None
  1106.  
  1107.             self.cups._end_operation()
  1108.             self.cups._set_prompt_allowed(True)
  1109.         else:
  1110.             self.printers = { }
  1111.             self.default_printer = None
  1112.         for name, printer in self.printers.iteritems():
  1113.             self.servers.add(printer.getServer())
  1114.         
  1115.         userdef = userdefault.UserDefaultPrinter().get()
  1116.         local_printers = []
  1117.         local_classes = []
  1118.         remote_printers = []
  1119.         remote_classes = []
  1120.         if isinstance(self.current_groups_pane_item, AllPrintersItem) or isinstance(self.current_groups_pane_item, SavedSearchGroupItem):
  1121.             delete_action = self.ui_manager.get_action('/delete-printer')
  1122.             delete_action.set_properties(label = None)
  1123.             printers_set = self.printers
  1124.         elif isinstance(self.current_groups_pane_item, FavouritesItem):
  1125.             printers_set = { }
  1126.         elif isinstance(self.current_groups_pane_item, StaticGroupItem):
  1127.             delete_action = self.ui_manager.get_action('/delete-printer')
  1128.             delete_action.set_properties(label = _('Remove from Group'))
  1129.             printers_set = { }
  1130.             deleted_printers = []
  1131.             for printer_name in self.current_groups_pane_item.printer_queues:
  1132.                 
  1133.                 try:
  1134.                     printer = self.printers[printer_name]
  1135.                     printers_set[printer_name] = printer
  1136.                 continue
  1137.                 except KeyError:
  1138.                     deleted_printers.append(printer_name)
  1139.                     continue
  1140.                 
  1141.  
  1142.             
  1143.             self.current_groups_pane_item.remove_queues(deleted_printers)
  1144.         else:
  1145.             printers_set = self.printers
  1146.             nonfatalException()
  1147.         if len(self.current_filter_text) > 0:
  1148.             printers_subset = { }
  1149.             pattern = re.compile(self.current_filter_text, re.I)
  1150.             if self.current_filter_mode == 'filter-name':
  1151.                 for name in printers_set.keys():
  1152.                     if pattern.search(name) != None:
  1153.                         printers_subset[name] = printers_set[name]
  1154.                         continue
  1155.                 
  1156.             elif self.current_filter_mode == 'filter-description':
  1157.                 for name, printer in printers_set.iteritems():
  1158.                     if pattern.search(printer.info) != None:
  1159.                         printers_subset[name] = printers_set[name]
  1160.                         continue
  1161.                 
  1162.             elif self.current_filter_mode == 'filter-location':
  1163.                 for name, printer in printers_set.iteritems():
  1164.                     if pattern.search(printer.location) != None:
  1165.                         printers_subset[name] = printers_set[name]
  1166.                         continue
  1167.                 
  1168.             elif self.current_filter_mode == 'filter-manufacturer':
  1169.                 for name, printer in printers_set.iteritems():
  1170.                     if pattern.search(printer.make_and_model) != None:
  1171.                         printers_subset[name] = printers_set[name]
  1172.                         continue
  1173.                 
  1174.             else:
  1175.                 nonfatalException()
  1176.             printers_set = printers_subset
  1177.         
  1178.         if not self.view_discovered_printers.get_active():
  1179.             printers_subset = { }
  1180.             for name, printer in printers_set.iteritems():
  1181.                 if not printer.discovered:
  1182.                     printers_subset[name] = printer
  1183.                     continue
  1184.             
  1185.             printers_set = printers_subset
  1186.         
  1187.         for name, printer in printers_set.iteritems():
  1188.             if printer.remote:
  1189.                 if printer.is_class:
  1190.                     remote_classes.append(name)
  1191.                 else:
  1192.                     remote_printers.append(name)
  1193.             printer.is_class
  1194.             if printer.is_class:
  1195.                 local_classes.append(name)
  1196.                 continue
  1197.             local_printers.append(name)
  1198.         
  1199.         local_printers.sort()
  1200.         local_classes.sort()
  1201.         remote_printers.sort()
  1202.         remote_classes.sort()
  1203.         self.mainlist.clear()
  1204.         PRINTER_TYPE = {
  1205.             'discovered-printer': (_('Network printer (discovered)'), 'i-network-printer'),
  1206.             'discovered-class': (_('Network class (discovered)'), 'i-network-printer'),
  1207.             'local-printer': (_('Printer'), 'gnome-dev-printer'),
  1208.             'local-fax': (_('Fax'), 'gnome-dev-printer'),
  1209.             'local-class': (_('Class'), 'gnome-dev-printer'),
  1210.             'ipp-printer': (_('Network printer'), 'i-network-printer'),
  1211.             'smb-printer': (_('Network print share'), 'gnome-dev-printer'),
  1212.             'network-printer': (_('Network printer'), 'i-network-printer') }
  1213.         theme = gtk.icon_theme_get_default()
  1214.         for printers in (local_printers, local_classes, remote_printers, remote_classes):
  1215.             if not printers:
  1216.                 continue
  1217.             
  1218.             for name in printers:
  1219.                 type = 'local-printer'
  1220.                 object = printers_set[name]
  1221.                 if object.discovered:
  1222.                     if object.is_class:
  1223.                         type = 'discovered-class'
  1224.                     else:
  1225.                         type = 'discovered-printer'
  1226.                 elif object.is_class:
  1227.                     type = 'local-class'
  1228.                 else:
  1229.                     (scheme, rest) = urllib.splittype(object.device_uri)
  1230.                     if scheme == 'ipp':
  1231.                         type = 'ipp-printer'
  1232.                     elif scheme == 'smb':
  1233.                         type = 'smb-printer'
  1234.                     elif scheme == 'hpfax':
  1235.                         type = 'local-fax'
  1236.                     elif scheme in ('socket', 'lpd'):
  1237.                         type = 'network-printer'
  1238.                     
  1239.                 (tip, icon) = PRINTER_TYPE[type]
  1240.                 (w, h) = gtk.icon_size_lookup(gtk.ICON_SIZE_DIALOG)
  1241.                 
  1242.                 try:
  1243.                     pixbuf = theme.load_icon(icon, w, 0)
  1244.                 except gobject.GError:
  1245.                     pixbuf = None
  1246.                     for p in [
  1247.                         iconpath,
  1248.                         'icons/']:
  1249.                         
  1250.                         try:
  1251.                             pixbuf = gtk.gdk.pixbuf_new_from_file('%s%s.png' % (p, icon))
  1252.                         continue
  1253.                         except gobject.GError:
  1254.                             continue
  1255.                         
  1256.  
  1257.                     
  1258.                     if pixbuf == None:
  1259.                         
  1260.                         try:
  1261.                             pixbuf = theme.load_icon('printer', w, 0)
  1262.                         pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h)
  1263.                         pixbuf.fill(0)
  1264.  
  1265.                     
  1266.                 except:
  1267.                     None<EXCEPTION MATCH>gobject.GError
  1268.  
  1269.                 def_emblem = None
  1270.                 emblem = None
  1271.                 if name == self.default_printer:
  1272.                     def_emblem = 'emblem-default'
  1273.                 elif name == userdef:
  1274.                     def_emblem = 'emblem-favorite'
  1275.                 
  1276.                 if not emblem:
  1277.                     attrs = object.other_attributes
  1278.                     reasons = attrs.get('printer-state-reasons', [])
  1279.                     worst_reason = None
  1280.                     for reason in reasons:
  1281.                         if reason == 'none':
  1282.                             break
  1283.                         
  1284.                         if reason == 'paused':
  1285.                             emblem = gtk.STOCK_MEDIA_PAUSE
  1286.                             continue
  1287.                         
  1288.                         r = statereason.StateReason(object.name, reason)
  1289.                         if worst_reason == None:
  1290.                             worst_reason = r
  1291.                             continue
  1292.                         if r > worst_reason:
  1293.                             worst_reason = r
  1294.                             continue
  1295.                     
  1296.                     if worst_reason:
  1297.                         level = worst_reason.get_level()
  1298.                         emblem = worst_reason.LEVEL_ICON[level]
  1299.                     
  1300.                 
  1301.                 if not emblem and not (object.enabled):
  1302.                     emblem = gtk.STOCK_MEDIA_PAUSE
  1303.                 
  1304.                 if object.rejecting:
  1305.                     copy = pixbuf.copy()
  1306.                     copy.fill(0)
  1307.                     pixbuf.composite(copy, 0, 0, copy.get_width(), copy.get_height(), 0, 0, 1, 1, gtk.gdk.INTERP_BILINEAR, 127)
  1308.                     pixbuf = copy
  1309.                 
  1310.                 if def_emblem:
  1311.                     (w, h) = gtk.icon_size_lookup(gtk.ICON_SIZE_DIALOG)
  1312.                     default_emblem = theme.load_icon(def_emblem, w / 2, 0)
  1313.                     copy = pixbuf.copy()
  1314.                     default_emblem.composite(copy, 0, 0, copy.get_width(), copy.get_height(), 0, 0, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
  1315.                     pixbuf = copy
  1316.                 
  1317.                 if emblem:
  1318.                     (w, h) = gtk.icon_size_lookup(gtk.ICON_SIZE_DIALOG)
  1319.                     other_emblem = theme.load_icon(emblem, w / 2, 0)
  1320.                     copy = pixbuf.copy()
  1321.                     other_emblem.composite(copy, 0, 0, copy.get_width(), copy.get_height(), copy.get_width() / 2, copy.get_height() / 2, 1, 1, gtk.gdk.INTERP_NEAREST, 255)
  1322.                     pixbuf = copy
  1323.                 
  1324.                 self.mainlist.append(row = [
  1325.                     object,
  1326.                     pixbuf,
  1327.                     name,
  1328.                     tip])
  1329.             
  1330.         
  1331.         model = self.dests_iconview.get_model()
  1332.         
  1333.         def maybe_select(model, path, iter):
  1334.             name = unicode(model.get_value(iter, 2))
  1335.             if name in selected_printers:
  1336.                 self.dests_iconview.select_path(path)
  1337.             
  1338.  
  1339.         model.foreach(maybe_select)
  1340.         if self.printer != None and self.printer.name not in self.printers.keys():
  1341.             self.PrinterPropertiesDialog.response(gtk.RESPONSE_CANCEL)
  1342.         
  1343.  
  1344.     
  1345.     def on_connect_servername_changed(self, widget):
  1346.         self.btnConnect.set_sensitive(len(widget.get_active_text()) > 0)
  1347.  
  1348.     
  1349.     def on_connect_activate(self, widget):
  1350.         servers = self.getServers()
  1351.         if not self.printer or self.printer.getServer():
  1352.             pass
  1353.         current_server = cups.getServer()
  1354.         store = gtk.ListStore(gobject.TYPE_STRING)
  1355.         self.cmbServername.set_model(store)
  1356.         for server in servers:
  1357.             self.cmbServername.append_text(server)
  1358.         
  1359.         self.cmbServername.show()
  1360.         self.cmbServername.child.set_text(current_server)
  1361.         self.chkEncrypted.set_active(cups.getEncryption() == cups.HTTP_ENCRYPT_ALWAYS)
  1362.         self.cmbServername.child.set_activates_default(True)
  1363.         self.cmbServername.grab_focus()
  1364.         self.ConnectDialog.set_transient_for(self.PrintersWindow)
  1365.         response = self.ConnectDialog.run()
  1366.         self.ConnectDialog.hide()
  1367.         if response != gtk.RESPONSE_OK:
  1368.             return None
  1369.         if self.chkEncrypted.get_active():
  1370.             cups.setEncryption(cups.HTTP_ENCRYPT_ALWAYS)
  1371.         else:
  1372.             cups.setEncryption(cups.HTTP_ENCRYPT_IF_REQUESTED)
  1373.         self.connect_encrypt = cups.getEncryption()
  1374.         servername = self.cmbServername.child.get_text()
  1375.         self.lblConnecting.set_markup(_('<i>Opening connection to %s</i>') % servername)
  1376.         self.newPrinterGUI.dropPPDs()
  1377.         self.ConnectingDialog.set_transient_for(self.PrintersWindow)
  1378.         self.ConnectingDialog.show()
  1379.         gobject.timeout_add(40, self.update_connecting_pbar)
  1380.         self.connect_server = servername
  1381.         cups.setServer(self.connect_server)
  1382.         cups.setUser('')
  1383.         self.connect_user = cups.getUser()
  1384.         self.connect_thread = thread.start_new_thread(self.connect, (self.PrintersWindow,))
  1385.  
  1386.     
  1387.     def update_connecting_pbar(self):
  1388.         if not self.ConnectingDialog.get_property('visible'):
  1389.             return False
  1390.         self.pbarConnecting.pulse()
  1391.         return True
  1392.  
  1393.     
  1394.     def on_connectingdialog_delete(self, widget, event):
  1395.         self.on_cancel_connect_clicked(widget)
  1396.         return True
  1397.  
  1398.     
  1399.     def on_cancel_connect_clicked(self, widget):
  1400.         """
  1401.         Stop connection to new server
  1402.         (Doesn't really stop but sets flag for the connecting thread to
  1403.         ignore the connection)
  1404.         """
  1405.         self.connect_thread = None
  1406.         self.ConnectingDialog.hide()
  1407.  
  1408.     
  1409.     def connect(self, parent = None):
  1410.         '''
  1411.         Open a connection to a new server. Is executed in a separate thread!
  1412.         '''
  1413.         cups.setUser(self.connect_user)
  1414.         if self.connect_server[0] == '/':
  1415.             
  1416.             try:
  1417.                 connection = cups.Connection(host = self.connect_server, encryption = self.connect_encrypt)
  1418.                 del connection
  1419.             except RuntimeError:
  1420.                 cups.setServer('localhost')
  1421.             except:
  1422.                 None<EXCEPTION MATCH>RuntimeError
  1423.                 nonfatalException()
  1424.             
  1425.  
  1426.         None<EXCEPTION MATCH>RuntimeError
  1427.         
  1428.         try:
  1429.             connection = authconn.Connection(parent, host = self.connect_server, encryption = self.connect_encrypt)
  1430.             self.newPrinterGUI.dropPPDs()
  1431.         except RuntimeError:
  1432.             s = None
  1433.             if self.connect_thread != thread.get_ident():
  1434.                 return None
  1435.             gtk.gdk.threads_enter()
  1436.             self.ConnectingDialog.hide()
  1437.             show_IPP_Error(None, s, parent)
  1438.             gtk.gdk.threads_leave()
  1439.             return None
  1440.             self.connect_thread != thread.get_ident()
  1441.             except cups.IPPError:
  1442.                 (e, s) = None
  1443.                 if self.connect_thread != thread.get_ident():
  1444.                     return None
  1445.                 gtk.gdk.threads_enter()
  1446.                 self.ConnectingDialog.hide()
  1447.                 show_IPP_Error(e, s, parent)
  1448.                 gtk.gdk.threads_leave()
  1449.                 return None
  1450.                 self.connect_thread != thread.get_ident()
  1451.                 nonfatalException()
  1452.             
  1453.  
  1454.         if self.connect_thread != thread.get_ident():
  1455.             return None
  1456.         gtk.gdk.threads_enter()
  1457.         
  1458.         try:
  1459.             self.ConnectingDialog.hide()
  1460.             self.cups = connection
  1461.             self.setConnected()
  1462.             self.populateList()
  1463.         except cups.HTTPError:
  1464.             self.connect_thread != thread.get_ident()
  1465.             (s,) = self.connect_thread != thread.get_ident()
  1466.             None<EXCEPTION MATCH>cups.IPPError
  1467.             self.cups = None
  1468.             self.setConnected()
  1469.             self.populateList()
  1470.             show_HTTP_Error(s, parent)
  1471.         except:
  1472.             self.connect_thread != thread.get_ident()
  1473.             None<EXCEPTION MATCH>cups.IPPError
  1474.             nonfatalException()
  1475.  
  1476.         gtk.gdk.threads_leave()
  1477.  
  1478.     
  1479.     def reconnect(self):
  1480.         '''Reconnect to CUPS after the server has reloaded.'''
  1481.         attempt = 1
  1482.         while attempt <= 5:
  1483.             
  1484.             try:
  1485.                 time.sleep(1)
  1486.                 self.cups._connect()
  1487.             continue
  1488.             except RuntimeError:
  1489.                 attempt += 1
  1490.                 continue
  1491.             
  1492.  
  1493.             None<EXCEPTION MATCH>RuntimeError
  1494.  
  1495.     
  1496.     def on_btnCancelConnect_clicked(self, widget):
  1497.         '''Close Connect dialog'''
  1498.         self.ConnectWindow.hide()
  1499.  
  1500.     
  1501.     def on_btnRefresh_clicked(self, button):
  1502.         if self.cups == None:
  1503.             
  1504.             try:
  1505.                 self.cups = authconn.Connection(self.PrintersWindow)
  1506.             except RuntimeError:
  1507.                 pass
  1508.  
  1509.             self.setConnected()
  1510.         
  1511.         self.populateList()
  1512.  
  1513.     
  1514.     def on_printer_changed(self, widget):
  1515.         if isinstance(widget, gtk.CheckButton):
  1516.             value = widget.get_active()
  1517.         elif isinstance(widget, gtk.Entry):
  1518.             value = widget.get_text()
  1519.         elif isinstance(widget, gtk.RadioButton):
  1520.             value = widget.get_active()
  1521.         elif isinstance(widget, gtk.ComboBox):
  1522.             model = widget.get_model()
  1523.             iter = widget.get_active_iter()
  1524.             value = model.get_value(iter, 1)
  1525.         else:
  1526.             raise ValueError, 'Widget type not supported (yet)'
  1527.         p = isinstance(widget, gtk.CheckButton).printer
  1528.         old_values = {
  1529.             self.entPDescription: p.info,
  1530.             self.entPLocation: p.location,
  1531.             self.entPDevice: p.device_uri,
  1532.             self.chkPEnabled: p.enabled,
  1533.             self.chkPAccepting: not (p.rejecting),
  1534.             self.chkPShared: p.is_shared,
  1535.             self.cmbPStartBanner: p.job_sheet_start,
  1536.             self.cmbPEndBanner: p.job_sheet_end,
  1537.             self.cmbPErrorPolicy: p.error_policy,
  1538.             self.cmbPOperationPolicy: p.op_policy,
  1539.             self.rbtnPAllow: p.default_allow }
  1540.         old_value = old_values[widget]
  1541.         if old_value == value:
  1542.             self.changed.discard(widget)
  1543.         else:
  1544.             self.changed.add(widget)
  1545.         self.setDataButtonState()
  1546.  
  1547.     
  1548.     def option_changed(self, option):
  1549.         if option.is_changed():
  1550.             self.changed.add(option)
  1551.         else:
  1552.             self.changed.discard(option)
  1553.         if option.conflicts:
  1554.             self.conflicts.add(option)
  1555.         else:
  1556.             self.conflicts.discard(option)
  1557.         self.setDataButtonState()
  1558.         if self.option_manualfeed and self.option_inputslot and option == self.option_manualfeed:
  1559.             if option.get_current_value() == 'True':
  1560.                 self.option_inputslot.disable()
  1561.             else:
  1562.                 self.option_inputslot.enable()
  1563.         
  1564.  
  1565.     
  1566.     def getPUsers(self):
  1567.         '''return list of usernames from the GUI'''
  1568.         model = self.tvPUsers.get_model()
  1569.         result = []
  1570.         (model.foreach,)((lambda model, path, iter: result.append(model.get(iter, 0)[0])))
  1571.         result.sort()
  1572.         return result
  1573.  
  1574.     
  1575.     def setPUsers(self, users):
  1576.         '''write list of usernames inot the GUI'''
  1577.         model = self.tvPUsers.get_model()
  1578.         model.clear()
  1579.         for user in users:
  1580.             model.append((user,))
  1581.         
  1582.         self.on_entPUser_changed(self.entPUser)
  1583.         self.on_tvPUsers_cursor_changed(self.tvPUsers)
  1584.  
  1585.     
  1586.     def checkPUsersChanged(self):
  1587.         '''check if users in GUI and printer are different
  1588.         and set self.changed'''
  1589.         if self.getPUsers() != self.printer.except_users:
  1590.             self.changed.add(self.tvPUsers)
  1591.         else:
  1592.             self.changed.discard(self.tvPUsers)
  1593.         self.on_tvPUsers_cursor_changed(self.tvPUsers)
  1594.         self.setDataButtonState()
  1595.  
  1596.     
  1597.     def on_btnPAddUser_clicked(self, button):
  1598.         user = self.entPUser.get_text()
  1599.         if user:
  1600.             self.tvPUsers.get_model().insert(0, (user,))
  1601.             self.entPUser.set_text('')
  1602.         
  1603.         self.checkPUsersChanged()
  1604.  
  1605.     
  1606.     def on_btnPDelUser_clicked(self, button):
  1607.         (model, rows) = self.tvPUsers.get_selection().get_selected_rows()
  1608.         rows = [ gtk.TreeRowReference(model, row) for row in rows ]
  1609.         for row in rows:
  1610.             path = row.get_path()
  1611.             iter = model.get_iter(path)
  1612.             model.remove(iter)
  1613.         
  1614.         self.checkPUsersChanged()
  1615.  
  1616.     
  1617.     def on_entPUser_changed(self, widget):
  1618.         self.btnPAddUser.set_sensitive(bool(widget.get_text()))
  1619.  
  1620.     
  1621.     def on_tvPUsers_cursor_changed(self, widget):
  1622.         (model, rows) = widget.get_selection().get_selected_rows()
  1623.         self.btnPDelUser.set_sensitive(bool(rows))
  1624.  
  1625.     
  1626.     def on_job_option_reset(self, button):
  1627.         option = self.job_options_buttons[button]
  1628.         option.reset()
  1629.         if self.server_side_options.has_key(option.name):
  1630.             del self.server_side_options[option.name]
  1631.         
  1632.         if option.is_changed():
  1633.             self.changed.add(option)
  1634.         else:
  1635.             self.changed.discard(option)
  1636.         self.setDataButtonState()
  1637.  
  1638.     
  1639.     def on_job_option_changed(self, widget):
  1640.         if not self.printer:
  1641.             return None
  1642.         option = self.job_options_widgets[widget]
  1643.         option.changed()
  1644.         if option.is_changed():
  1645.             self.server_side_options[option.name] = option
  1646.             self.changed.add(option)
  1647.         elif self.server_side_options.has_key(option.name):
  1648.             del self.server_side_options[option.name]
  1649.         
  1650.         self.changed.discard(option)
  1651.         self.setDataButtonState()
  1652.  
  1653.     
  1654.     def draw_other_job_options(self, editable = True):
  1655.         n = len(self.other_job_options)
  1656.         if n == 0:
  1657.             self.tblJOOther.hide_all()
  1658.             return None
  1659.         self.tblJOOther.resize(n, 3)
  1660.         children = self.tblJOOther.get_children()
  1661.         for child in children:
  1662.             self.tblJOOther.remove(child)
  1663.         
  1664.         i = 0
  1665.         for opt in self.other_job_options:
  1666.             self.tblJOOther.attach(opt.label, 0, 1, i, i + 1, xoptions = gtk.FILL, yoptions = gtk.FILL)
  1667.             opt.label.set_alignment(0, 0.5)
  1668.             self.tblJOOther.attach(opt.selector, 1, 2, i, i + 1, xoptions = gtk.FILL, yoptions = 0)
  1669.             opt.selector.set_sensitive(editable)
  1670.             btn = gtk.Button(stock = 'gtk-remove')
  1671.             btn.connect('clicked', self.on_btnJOOtherRemove_clicked)
  1672.             btn.set_data('pyobject', opt)
  1673.             btn.set_sensitive(editable)
  1674.             self.tblJOOther.attach(btn, 2, 3, i, i + 1, xoptions = 0, yoptions = 0)
  1675.             i += 1
  1676.         
  1677.         self.tblJOOther.show_all()
  1678.  
  1679.     
  1680.     def add_job_option(self, name, value = '', supported = '', is_new = True, editable = True):
  1681.         option = options.OptionWidget(name, value, supported, self.option_changed)
  1682.         option.is_new = is_new
  1683.         self.other_job_options.append(option)
  1684.         self.draw_other_job_options(editable = editable)
  1685.         self.server_side_options[name] = option
  1686.         if name in self.changed:
  1687.             option.is_new = False
  1688.         
  1689.         self.changed.add(option)
  1690.         self.setDataButtonState()
  1691.         if is_new:
  1692.             option.selector.grab_focus()
  1693.         
  1694.  
  1695.     
  1696.     def on_btnJOOtherRemove_clicked(self, button):
  1697.         option = button.get_data('pyobject')
  1698.         self.other_job_options.remove(option)
  1699.         self.draw_other_job_options()
  1700.         if option.is_new:
  1701.             self.changed.discard(option)
  1702.         else:
  1703.             self.changed.add(option.name)
  1704.         del self.server_side_options[option.name]
  1705.         self.setDataButtonState()
  1706.  
  1707.     
  1708.     def on_btnNewJobOption_clicked(self, button):
  1709.         name = self.entNewJobOption.get_text()
  1710.         self.add_job_option(name)
  1711.         self.tblJOOther.show_all()
  1712.         self.entNewJobOption.set_text('')
  1713.         self.btnNewJobOption.set_sensitive(False)
  1714.         self.setDataButtonState()
  1715.  
  1716.     
  1717.     def on_entNewJobOption_changed(self, widget):
  1718.         text = self.entNewJobOption.get_text()
  1719.         if len(text) > 0:
  1720.             pass
  1721.         active = text not in self.server_side_options
  1722.         self.btnNewJobOption.set_sensitive(active)
  1723.  
  1724.     
  1725.     def on_entNewJobOption_activate(self, widget):
  1726.         self.on_btnNewJobOption_clicked(widget)
  1727.  
  1728.     
  1729.     def setDataButtonState(self):
  1730.         
  1731.         try:
  1732.             if self.ppd and not bool(self.changed) and self.printer.enabled:
  1733.                 pass
  1734.             possible = not (self.printer.rejecting)
  1735.             for button in [
  1736.                 self.btnPrintTestPage,
  1737.                 self.btnChangePPD,
  1738.                 self.btnSelectDevice]:
  1739.                 button.set_sensitive(possible)
  1740.             
  1741.             commands = self.printer.type & cups.CUPS_PRINTER_COMMANDS != 0
  1742.             if commands:
  1743.                 pass
  1744.             self.btnSelfTest.set_sensitive(possible)
  1745.             if commands:
  1746.                 pass
  1747.             self.btnCleanHeads.set_sensitive(possible)
  1748.         except:
  1749.             pass
  1750.  
  1751.         installablebold = False
  1752.         optionsbold = False
  1753.         if self.conflicts:
  1754.             debugprint('Conflicts detected')
  1755.             self.btnConflict.show()
  1756.             for option in self.conflicts:
  1757.                 if option.tab_label == self.lblPInstallOptions:
  1758.                     installablebold = True
  1759.                     continue
  1760.                 optionsbold = True
  1761.             
  1762.         else:
  1763.             self.btnConflict.hide()
  1764.         installabletext = _('Installable Options')
  1765.         optionstext = _('Printer Options')
  1766.         if installablebold:
  1767.             installabletext = '<b>%s</b>' % installabletext
  1768.         
  1769.         if optionsbold:
  1770.             optionstext = '<b>%s</b>' % optionstext
  1771.         
  1772.         self.lblPInstallOptions.set_markup(installabletext)
  1773.         self.lblPOptions.set_markup(optionstext)
  1774.         store = self.tvPrinterProperties.get_model()
  1775.         if store:
  1776.             for n in range(self.ntbkPrinter.get_n_pages()):
  1777.                 page = self.ntbkPrinter.get_nth_page(n)
  1778.                 label = self.ntbkPrinter.get_tab_label(page)
  1779.                 
  1780.                 try:
  1781.                     if label == self.lblPInstallOptions:
  1782.                         iter = store.get_iter((n,))
  1783.                         store.set_value(iter, 0, installabletext)
  1784.                     elif label == self.lblPOptions:
  1785.                         iter = store.get_iter((n,))
  1786.                         store.set_value(iter, 0, optionstext)
  1787.                 continue
  1788.                 except ValueError:
  1789.                     continue
  1790.                 
  1791.  
  1792.             
  1793.         
  1794.         if len(self.changed) > 0:
  1795.             pass
  1796.         self.btnPrinterPropertiesApply.set_sensitive(not (self.conflicts))
  1797.         if len(self.changed) > 0:
  1798.             pass
  1799.         self.btnPrinterPropertiesOK.set_sensitive(not (self.conflicts))
  1800.  
  1801.     
  1802.     def save_printer(self, printer, saveall = False, parent = None):
  1803.         if parent == None:
  1804.             parent = self.PrinterPropertiesDialog
  1805.         
  1806.         class_deleted = False
  1807.         name = printer.name
  1808.         if printer.is_class:
  1809.             self.cups._begin_operation(_('modifying class %s') % name)
  1810.         else:
  1811.             self.cups._begin_operation(_('modifying printer %s') % name)
  1812.         
  1813.         try:
  1814.             if not (printer.is_class) and self.ppd:
  1815.                 self.getPrinterSettings()
  1816.                 if self.ppd.nondefaultsMarked() or saveall:
  1817.                     self.cups.addPrinter(name, ppd = self.ppd)
  1818.                 
  1819.             
  1820.             if printer.is_class:
  1821.                 new_members = getCurrentClassMembers(self.tvClassMembers)
  1822.                 if not new_members:
  1823.                     dialog = gtk.MessageDialog(flags = 0, type = gtk.MESSAGE_WARNING, buttons = gtk.BUTTONS_YES_NO, message_format = _('This will delete this class!'))
  1824.                     dialog.format_secondary_text(_('Proceed anyway?'))
  1825.                     result = dialog.run()
  1826.                     dialog.destroy()
  1827.                     if result == gtk.RESPONSE_NO:
  1828.                         self.cups._end_operation()
  1829.                         return True
  1830.                     class_deleted = True
  1831.                 
  1832.                 old_members = printer.class_members[:]
  1833.                 for member in new_members:
  1834.                     if member in old_members:
  1835.                         old_members.remove(member)
  1836.                         continue
  1837.                     self.cups.addPrinterToClass(member, name)
  1838.                 
  1839.                 for member in old_members:
  1840.                     self.cups.deletePrinterFromClass(member, name)
  1841.                 
  1842.             
  1843.             location = self.entPLocation.get_text()
  1844.             info = self.entPDescription.get_text()
  1845.             device_uri = self.entPDevice.get_text()
  1846.             enabled = self.chkPEnabled.get_active()
  1847.             accepting = self.chkPAccepting.get_active()
  1848.             shared = self.chkPShared.get_active()
  1849.             if info != printer.info or saveall:
  1850.                 self.cups.setPrinterInfo(name, info)
  1851.             
  1852.             if location != printer.location or saveall:
  1853.                 self.cups.setPrinterLocation(name, location)
  1854.             
  1855.             if not (printer.is_class):
  1856.                 if device_uri != printer.device_uri or saveall:
  1857.                     self.cups.setPrinterDevice(name, device_uri)
  1858.                 
  1859.             if enabled != printer.enabled or saveall:
  1860.                 self.printer.setEnabled(enabled)
  1861.             
  1862.             if accepting == printer.rejecting or saveall:
  1863.                 self.printer.setAccepting(accepting)
  1864.             
  1865.             if shared != printer.is_shared or saveall:
  1866.                 self.printer.setShared(shared)
  1867.             
  1868.             
  1869.             def get_combo_value(cmb):
  1870.                 model = cmb.get_model()
  1871.                 iter = cmb.get_active_iter()
  1872.                 return model.get_value(iter, 1)
  1873.  
  1874.             job_sheet_start = get_combo_value(self.cmbPStartBanner)
  1875.             job_sheet_end = get_combo_value(self.cmbPEndBanner)
  1876.             error_policy = get_combo_value(self.cmbPErrorPolicy)
  1877.             op_policy = get_combo_value(self.cmbPOperationPolicy)
  1878.             if job_sheet_start != printer.job_sheet_start or job_sheet_end != printer.job_sheet_end or saveall:
  1879.                 printer.setJobSheets(job_sheet_start, job_sheet_end)
  1880.             
  1881.             if error_policy != printer.error_policy or saveall:
  1882.                 printer.setErrorPolicy(error_policy)
  1883.             
  1884.             if op_policy != printer.op_policy or saveall:
  1885.                 printer.setOperationPolicy(op_policy)
  1886.             
  1887.             default_allow = self.rbtnPAllow.get_active()
  1888.             except_users = self.getPUsers()
  1889.             if default_allow != printer.default_allow or except_users != printer.except_users or saveall:
  1890.                 printer.setAccess(default_allow, except_users)
  1891.             
  1892.             for option in printer.attributes:
  1893.                 if option not in self.server_side_options:
  1894.                     printer.unsetOption(option)
  1895.                     continue
  1896.             
  1897.             for option in self.server_side_options.itervalues():
  1898.                 if (option.is_changed() or saveall) and option.get_current_value() != option.system_default:
  1899.                     printer.setOption(option.name, option.get_current_value())
  1900.                     continue
  1901.         except cups.IPPError:
  1902.             (e, s) = None
  1903.             show_IPP_Error(e, s, parent)
  1904.             self.cups._end_operation()
  1905.             return True
  1906.  
  1907.         self.cups._end_operation()
  1908.         self.changed = set()
  1909.         if not (self.cups._use_pk) and not self.__dict__.has_key('server_settings'):
  1910.             self.cups._begin_operation(_('fetching server settings'))
  1911.             
  1912.             try:
  1913.                 self.server_settings = self.cups.adminGetServerSettings()
  1914.             except:
  1915.                 nonfatalException()
  1916.  
  1917.             self.cups._end_operation()
  1918.         
  1919.         if class_deleted:
  1920.             self.monitor.update()
  1921.         else:
  1922.             self.cups._begin_operation(_('obtaining queue details'))
  1923.             
  1924.             try:
  1925.                 printers = cupshelpers.getPrinters(self.cups)
  1926.                 this_printer = {
  1927.                     name: printers[name] }
  1928.                 self.printers.update(this_printer)
  1929.             except cups.IPPError:
  1930.                 (e, s) = None
  1931.                 show_IPP_Error(e, s, self.PrinterPropertiesDialog)
  1932.             except KeyError:
  1933.                 self.populateList()
  1934.  
  1935.             self.cups._end_operation()
  1936.         return False
  1937.  
  1938.     
  1939.     def getPrinterSettings(self):
  1940.         for option in self.options.itervalues():
  1941.             option.writeback()
  1942.         
  1943.  
  1944.     
  1945.     def on_tvPrinterProperties_selection_changed(self, selection):
  1946.         (model, iter) = selection.get_selected()
  1947.         if iter:
  1948.             self.printer_properties_last_iter_selected = iter
  1949.         else:
  1950.             
  1951.             try:
  1952.                 iter = self.printer_properties_last_iter_selected
  1953.             except AttributeError:
  1954.                 return None
  1955.  
  1956.             if model.iter_is_valid(iter):
  1957.                 selection.select_iter(iter)
  1958.             
  1959.  
  1960.     
  1961.     def on_tvPrinterProperties_cursor_changed(self, treeview):
  1962.         (path, column) = treeview.get_cursor()
  1963.         if path != None:
  1964.             model = treeview.get_model()
  1965.             iter = model.get_iter(path)
  1966.             n = model.get_value(iter, 1)
  1967.             self.ntbkPrinter.set_current_page(n)
  1968.         
  1969.  
  1970.     
  1971.     def set_system_or_user_default_printer(self, name):
  1972.         userdef = userdefault.UserDefaultPrinter()
  1973.         if name == self.default_printer:
  1974.             userdef.clear()
  1975.             self.populateList()
  1976.             return None
  1977.         userdefault.UserDefaultPrompt(self.set_default_printer, self.populateList, name, _('Set Default Printer'), self.PrintersWindow, _('Do you want to set this as the system-wide default printer?'), _('Set as the _system-wide default printer'), _('_Clear my personal default setting'), _('Set as my _personal default printer'))
  1978.  
  1979.     
  1980.     def set_default_printer(self, name):
  1981.         printer = self.printers[name]
  1982.         reload = False
  1983.         self.cups._begin_operation(_('setting default printer'))
  1984.         
  1985.         try:
  1986.             reload = printer.setAsDefault()
  1987.         except cups.HTTPError:
  1988.             (s,) = None
  1989.             show_HTTP_Error(s, self.PrintersWindow)
  1990.             self.cups._end_operation()
  1991.             return None
  1992.             except cups.IPPError:
  1993.                 (e, msg) = None
  1994.                 show_IPP_Error(e, msg, self.PrintersWindow)
  1995.                 self.cups._end_operation()
  1996.                 return None
  1997.             else:
  1998.                 self.cups._end_operation()
  1999.                 if reload:
  2000.                     self.reconnect()
  2001.                 
  2002.  
  2003.         
  2004.         try:
  2005.             self.populateList()
  2006.         except cups.HTTPError:
  2007.             (s,) = None
  2008.             self.cups = None
  2009.             self.setConnected()
  2010.             self.populateList()
  2011.             show_HTTP_Error(s, self.PrintersWindow)
  2012.  
  2013.  
  2014.     
  2015.     def on_btnPrintTestPage_clicked(self, button):
  2016.         if self.ppd == False:
  2017.             return None
  2018.         custom_testpage = None
  2019.         if self.ppd != False:
  2020.             opt = self.ppd.findOption('PageSize')
  2021.             if opt:
  2022.                 custom_testpage = os.path.join(pkgdata, 'testpage-%s.ps' % opt.defchoice.lower())
  2023.             
  2024.         
  2025.         user = cups.getUser()
  2026.         cups.setUser('')
  2027.         
  2028.         try:
  2029.             c = authconn.Connection(self.PrintersWindow, try_as_root = False, host = self.connect_server, encryption = self.connect_encrypt)
  2030.         except RuntimeError:
  2031.             s = None
  2032.             show_IPP_Error(None, s, self.PrintersWindow)
  2033.             return None
  2034.  
  2035.         job_id = None
  2036.         c._begin_operation(_('printing test page'))
  2037.         
  2038.         try:
  2039.             if custom_testpage and os.path.exists(custom_testpage):
  2040.                 debugprint('Printing custom test page ' + custom_testpage)
  2041.                 job_id = c.printTestPage(self.printer.name, file = custom_testpage)
  2042.             else:
  2043.                 debugprint('Printing default test page')
  2044.                 job_id = c.printTestPage(self.printer.name)
  2045.         except cups.IPPError:
  2046.             (e, msg) = None
  2047.             if e == cups.IPP_NOT_AUTHORIZED and self.connect_server != 'localhost' and self.connect_server[0] != '/':
  2048.                 show_error_dialog(_('Not possible'), _('The remote server did not accept the print job, most likely because the printer is not shared.'), self.PrintersWindow)
  2049.             else:
  2050.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2051.         except:
  2052.             self.connect_server[0] != '/'
  2053.  
  2054.         c._end_operation()
  2055.         cups.setUser(user)
  2056.         if job_id != None:
  2057.             show_info_dialog(_('Submitted'), _('Test page submitted as job %d') % job_id, parent = self.PrintersWindow)
  2058.         
  2059.  
  2060.     
  2061.     def maintenance_command(self, command):
  2062.         (tmpfd, tmpfname) = tempfile.mkstemp()
  2063.         os.write(tmpfd, '#CUPS-COMMAND\n%s\n' % command)
  2064.         os.close(tmpfd)
  2065.         self.cups._begin_operation(_('sending maintenance command'))
  2066.         
  2067.         try:
  2068.             format = 'application/vnd.cups-command'
  2069.             job_id = self.cups.printTestPage(self.printer.name, format = format, file = tmpfname, user = self.connect_user)
  2070.             show_info_dialog(_('Submitted'), _('Maintenance command submitted as job %d') % job_id, parent = self.PrintersWindow)
  2071.         except cups.IPPError:
  2072.             (e, msg) = None
  2073.             if e == cups.IPP_NOT_AUTHORIZED and self.printer.name != 'localhost':
  2074.                 show_error_dialog(_('Not possible'), _('The remote server did not accept the print job, most likely because the printer is not shared.'), self.PrintersWindow)
  2075.             else:
  2076.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2077.         except:
  2078.             self.printer.name != 'localhost'
  2079.  
  2080.         self.cups._end_operation()
  2081.         os.unlink(tmpfname)
  2082.  
  2083.     
  2084.     def on_btnSelfTest_clicked(self, button):
  2085.         self.maintenance_command('PrintSelfTestPage')
  2086.  
  2087.     
  2088.     def on_btnCleanHeads_clicked(self, button):
  2089.         self.maintenance_command('Clean all')
  2090.  
  2091.     
  2092.     def fillComboBox(self, combobox, values, value, translationdict = None):
  2093.         if translationdict == None:
  2094.             translationdict = ppdippstr.TranslactionDict()
  2095.         
  2096.         model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
  2097.         combobox.set_model(model)
  2098.         set_active = False
  2099.         for nr, val in enumerate(values):
  2100.             model.append([
  2101.                 translationdict.get(val),
  2102.                 val])
  2103.             if val == value:
  2104.                 combobox.set_active(nr)
  2105.                 set_active = True
  2106.                 continue
  2107.         
  2108.         if not set_active:
  2109.             combobox.set_active(0)
  2110.         
  2111.  
  2112.     
  2113.     def fillPrinterTab(self, name):
  2114.         self.changed = set()
  2115.         self.options = { }
  2116.         self.conflicts = set()
  2117.         printer = self.printers[name]
  2118.         self.printer = printer
  2119.         printer.getAttributes()
  2120.         
  2121.         try:
  2122.             publishing = printer.other_attributes['server-is-sharing-printers']
  2123.             self.server_is_publishing = publishing
  2124.         except KeyError:
  2125.             pass
  2126.  
  2127.         editable = not (self.printer.discovered)
  2128.         editablePPD = not (self.printer.remote)
  2129.         
  2130.         try:
  2131.             self.ppd = printer.getPPD()
  2132.             self.ppd_local = printer.getPPD()
  2133.             if self.ppd_local != False:
  2134.                 self.ppd_local.localize()
  2135.         except cups.IPPError:
  2136.             (e, m) = None
  2137.             show_IPP_Error(e, m, self.PrintersWindow)
  2138.             self.ppd = False
  2139.         except RuntimeError:
  2140.             show_error_dialog(_('Error'), _('There was a problem connecting to the CUPS server.'), self.PrintersWindow)
  2141.             raise 
  2142.  
  2143.         for widget in (self.entPDescription, self.entPLocation, self.entPDevice):
  2144.             widget.set_editable(editable)
  2145.         
  2146.         for widget in (self.btnSelectDevice, self.btnChangePPD, self.chkPEnabled, self.chkPAccepting, self.chkPShared, self.cmbPStartBanner, self.cmbPEndBanner, self.cmbPErrorPolicy, self.cmbPOperationPolicy, self.rbtnPAllow, self.rbtnPDeny, self.tvPUsers, self.entPUser, self.btnPAddUser, self.btnPDelUser):
  2147.             widget.set_sensitive(editable)
  2148.         
  2149.         self.entPDescription.set_text(printer.info)
  2150.         self.entPLocation.set_text(printer.location)
  2151.         uri = printer.device_uri
  2152.         self.entPDevice.set_text(uri)
  2153.         self.changed.discard(self.entPDevice)
  2154.         for widget in (self.lblPMakeModel2, self.lblPMakeModel, self.btnChangePPD, self.lblPDevice2, self.entPDevice, self.btnSelectDevice):
  2155.             if printer.is_class:
  2156.                 widget.hide()
  2157.                 continue
  2158.             widget.show()
  2159.         
  2160.         
  2161.         try:
  2162.             if printer.is_shared:
  2163.                 if self.server_is_publishing:
  2164.                     self.lblNotPublished.hide_all()
  2165.                 else:
  2166.                     self.lblNotPublished.show_all()
  2167.             else:
  2168.                 self.lblNotPublished.hide_all()
  2169.         except:
  2170.             nonfatalException()
  2171.             self.lblNotPublished.hide_all()
  2172.  
  2173.         self.cmbPStartBanner.set_sensitive(editable)
  2174.         self.cmbPEndBanner.set_sensitive(editable)
  2175.         self.cmbPErrorPolicy.set_sensitive(editable)
  2176.         self.cmbPOperationPolicy.set_sensitive(editable)
  2177.         self.entPUser.set_text('')
  2178.         self.server_side_options = { }
  2179.         for option in self.job_options_widgets.values():
  2180.             if option.name == 'media' and self.ppd:
  2181.                 opt = self.ppd.findOption('PageSize')
  2182.                 if opt:
  2183.                     option.set_default(opt.defchoice)
  2184.                 
  2185.             
  2186.             option_editable = editable
  2187.             
  2188.             try:
  2189.                 value = self.printer.attributes[option.name]
  2190.             except KeyError:
  2191.                 option.reinit(None)
  2192.  
  2193.             
  2194.             try:
  2195.                 if self.printer.possible_attributes.has_key(option.name):
  2196.                     supported = self.printer.possible_attributes[option.name][1]
  2197.                     option.reinit(value, supported = supported)
  2198.                 else:
  2199.                     option.reinit(value)
  2200.                 self.server_side_options[option.name] = option
  2201.             except:
  2202.                 option_editable = False
  2203.                 show_error_dialog(_('Error'), _("Option '%s' has value '%s' and cannot be edited.") % (option.name, value), self.PrintersWindow)
  2204.  
  2205.             option.widget.set_sensitive(option_editable)
  2206.             if not editable:
  2207.                 option.button.set_sensitive(False)
  2208.                 continue
  2209.         
  2210.         self.other_job_options = []
  2211.         self.draw_other_job_options(editable = editable)
  2212.         for option in self.printer.attributes.keys():
  2213.             if self.server_side_options.has_key(option):
  2214.                 continue
  2215.             
  2216.             value = self.printer.attributes[option]
  2217.             if self.printer.possible_attributes.has_key(option):
  2218.                 supported = self.printer.possible_attributes[option][1]
  2219.             elif isinstance(value, bool):
  2220.                 supported = [
  2221.                     'true',
  2222.                     'false']
  2223.                 value = str(value).lower()
  2224.             else:
  2225.                 supported = ''
  2226.                 value = str(value)
  2227.             self.add_job_option(option, value = value, supported = supported, is_new = False, editable = editable)
  2228.         
  2229.         self.entNewJobOption.set_text('')
  2230.         self.entNewJobOption.set_sensitive(editable)
  2231.         self.btnNewJobOption.set_sensitive(False)
  2232.         if printer.is_class:
  2233.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2234.             if tab_nr != -1:
  2235.                 self.ntbkPrinter.remove_page(tab_nr)
  2236.             
  2237.             self.fillClassMembers(name, editable)
  2238.         else:
  2239.             self.fillPrinterOptions(name, editablePPD)
  2240.         self.updateMarkerLevels()
  2241.         self.updateStateReasons()
  2242.         self.updatePrinterPropertiesTreeView()
  2243.         self.changed = set()
  2244.         self.updatePrinterProperties()
  2245.         self.setDataButtonState()
  2246.  
  2247.     
  2248.     def updatePrinterPropertiesTreeView(self):
  2249.         store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
  2250.         self.ntbkPrinter.set_show_tabs(False)
  2251.         for n in range(self.ntbkPrinter.get_n_pages()):
  2252.             page = self.ntbkPrinter.get_nth_page(n)
  2253.             label = self.ntbkPrinter.get_tab_label(page)
  2254.             iter = store.append(None)
  2255.             store.set_value(iter, 0, label.get_text())
  2256.             store.set_value(iter, 1, n)
  2257.         
  2258.         sel = self.tvPrinterProperties.get_selection()
  2259.         self.tvPrinterProperties.set_model(store)
  2260.  
  2261.     
  2262.     def updateMarkerLevels(self):
  2263.         printer = self.printer
  2264.         for widget in self.vboxMarkerLevels.get_children():
  2265.             self.vboxMarkerLevels.remove(widget)
  2266.         
  2267.         marker_info = dict()
  2268.         for attr in [
  2269.             'marker-colors',
  2270.             'marker-names',
  2271.             'marker-types',
  2272.             'marker-levels']:
  2273.             val = printer.other_attributes.get(attr, [])
  2274.             if type(val) != list:
  2275.                 val = [
  2276.                     val]
  2277.             
  2278.             marker_info[attr] = val
  2279.         
  2280.         markers = map((lambda color, name, type, level: (color, name, type, level)), marker_info['marker-colors'], marker_info['marker-names'], marker_info['marker-types'], marker_info['marker-levels'])
  2281.         debugprint(markers)
  2282.         can_refresh = self.printer.type & cups.CUPS_PRINTER_COMMANDS != 0
  2283.         self.btnRefreshMarkerLevels.set_sensitive(can_refresh)
  2284.         if len(markers) == 0:
  2285.             label = gtk.Label(_('Marker levels are not reported for this printer.'))
  2286.             label.set_line_wrap(True)
  2287.             label.set_alignment(0, 0)
  2288.             self.vboxMarkerLevels.pack_start(label, False, False, 0)
  2289.         else:
  2290.             num_markers = 0
  2291.             cols = len(markers)
  2292.             rows = 1 + (cols - 1) / 4
  2293.             if cols > 4:
  2294.                 cols = 4
  2295.             
  2296.             table = gtk.Table(rows = rows, columns = cols, homogeneous = True)
  2297.             table.set_col_spacings(6)
  2298.             table.set_row_spacings(12)
  2299.             self.vboxMarkerLevels.pack_start(table)
  2300.             for color, name, marker_type, level in markers:
  2301.                 if name == None:
  2302.                     name = ''
  2303.                 else:
  2304.                     ppd = printer.getPPD()
  2305.                     if ppd != False:
  2306.                         localized_name = ppd.localizeMarkerName(name)
  2307.                         if localized_name != None:
  2308.                             name = localized_name
  2309.                         
  2310.                     
  2311.                 row = num_markers / 4
  2312.                 col = num_markers % 4
  2313.                 vbox = gtk.VBox(spacing = 6)
  2314.                 subhbox = gtk.HBox()
  2315.                 inklevel = gtkinklevel.GtkInkLevel(color, level)
  2316.                 subhbox.pack_start(inklevel, True, False, 0)
  2317.                 vbox.pack_start(subhbox, False, False, 0)
  2318.                 label = gtk.Label(name)
  2319.                 label.set_line_wrap(True)
  2320.                 vbox.pack_start(label, False, False, 0)
  2321.                 table.attach(vbox, col, col + 1, row, row + 1)
  2322.                 num_markers += 1
  2323.             
  2324.         self.vboxMarkerLevels.show_all()
  2325.  
  2326.     
  2327.     def on_btnRefreshMarkerLevels_clicked(self, button):
  2328.         self.maintenance_command('ReportLevels')
  2329.  
  2330.     
  2331.     def updateStateReasons(self):
  2332.         printer = self.printer
  2333.         reasons = printer.other_attributes.get('printer-state-reasons', [])
  2334.         store = gtk.ListStore(str, str)
  2335.         any = False
  2336.         for reason in reasons:
  2337.             if reason == 'none':
  2338.                 break
  2339.             
  2340.             any = True
  2341.             iter = store.append(None)
  2342.             r = statereason.StateReason(printer.name, reason)
  2343.             if r.get_reason() == 'paused':
  2344.                 icon = gtk.STOCK_MEDIA_PAUSE
  2345.             else:
  2346.                 icon = statereason.StateReason.LEVEL_ICON[r.get_level()]
  2347.             store.set_value(iter, 0, icon)
  2348.             (title, text) = r.get_description()
  2349.             store.set_value(iter, 1, text)
  2350.         
  2351.         self.tvPrinterStateReasons.set_model(store)
  2352.         page = 0
  2353.         if any:
  2354.             page = 1
  2355.         
  2356.         self.ntbkPrinterStateReasons.set_current_page(page)
  2357.  
  2358.     
  2359.     def set_printer_state_reason_icon(self, column, cell, model, iter, *data):
  2360.         icon = model.get_value(iter, 0)
  2361.         theme = gtk.icon_theme_get_default()
  2362.         
  2363.         try:
  2364.             pixbuf = theme.load_icon(icon, 22, 0)
  2365.             cell.set_property('pixbuf', pixbuf)
  2366.         except gobject.GError:
  2367.             exc = None
  2368.  
  2369.  
  2370.     
  2371.     def set_printer_state_reason_text(self, column, cell, model, iter, *data):
  2372.         cell.set_property('text', model.get_value(iter, 1))
  2373.  
  2374.     
  2375.     def updatePrinterProperties(self):
  2376.         debugprint('update printer properties')
  2377.         printer = self.printer
  2378.         self.lblPMakeModel.set_text(printer.make_and_model)
  2379.         state = self.printer_states.get(printer.state, _('Unknown'))
  2380.         reason = printer.other_attributes.get('printer-state-message', '')
  2381.         if len(reason) > 0:
  2382.             state += ' - ' + reason
  2383.         
  2384.         self.lblPState.set_text(state)
  2385.         if len(self.changed) == 0:
  2386.             debugprint('no changes yet: full printer properties update')
  2387.             self.chkPEnabled.set_active(printer.enabled)
  2388.             self.chkPAccepting.set_active(not (printer.rejecting))
  2389.             self.chkPShared.set_active(printer.is_shared)
  2390.             self.fillComboBox(self.cmbPStartBanner, printer.job_sheets_supported, printer.job_sheet_start, ppdippstr.job_sheets)
  2391.             self.fillComboBox(self.cmbPEndBanner, printer.job_sheets_supported, printer.job_sheet_end, ppdippstr.job_sheets)
  2392.             self.fillComboBox(self.cmbPErrorPolicy, printer.error_policy_supported, printer.error_policy, ppdippstr.printer_error_policy)
  2393.             self.fillComboBox(self.cmbPOperationPolicy, printer.op_policy_supported, printer.op_policy, ppdippstr.printer_op_policy)
  2394.             self.rbtnPAllow.set_active(printer.default_allow)
  2395.             self.rbtnPDeny.set_active(not (printer.default_allow))
  2396.             self.setPUsers(printer.except_users)
  2397.             self.updateMarkerLevels()
  2398.             self.updateStateReasons()
  2399.             self.updatePrinterPropertiesTreeView()
  2400.         
  2401.  
  2402.     
  2403.     def fillPrinterOptions(self, name, editable):
  2404.         tab_nr = self.ntbkPrinter.page_num(self.algnClassMembers)
  2405.         if tab_nr != -1:
  2406.             self.ntbkPrinter.remove_page(tab_nr)
  2407.         
  2408.         for widget in self.vbPInstallOptions.get_children():
  2409.             self.vbPInstallOptions.remove(widget)
  2410.         
  2411.         for widget in self.vbPOptions.get_children():
  2412.             self.vbPOptions.remove(widget)
  2413.         
  2414.         if self.ntbkPrinter.page_num(self.swPOptions) == -1:
  2415.             self.ntbkPrinter.insert_page(self.swPOptions, self.lblPOptions, self.static_tabs)
  2416.         
  2417.         if not self.ppd:
  2418.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2419.             if tab_nr != -1:
  2420.                 self.ntbkPrinter.remove_page(tab_nr)
  2421.             
  2422.             tab_nr = self.ntbkPrinter.page_num(self.swPOptions)
  2423.             if tab_nr != -1:
  2424.                 self.ntbkPrinter.remove_page(tab_nr)
  2425.             
  2426.             return None
  2427.         ppd = self.ppd
  2428.         ppd.markDefaults()
  2429.         self.ppd_local.markDefaults()
  2430.         hasInstallableOptions = False
  2431.         for group in self.ppd_local.optionGroups:
  2432.             table = gtk.Table(1, 3, False)
  2433.             table.set_col_spacings(6)
  2434.             table.set_row_spacings(6)
  2435.             container.add(table)
  2436.             rows = 0
  2437.             self.option_inputslot = None
  2438.             self.option_manualfeed = None
  2439.             for nr, option in enumerate(group.options):
  2440.                 if option.keyword == 'PageRegion':
  2441.                     continue
  2442.                 
  2443.                 rows += 1
  2444.                 table.resize(rows, 3)
  2445.                 o = OptionWidget(option, ppd, self, tab_label = tab_label)
  2446.                 table.attach(o.conflictIcon, 0, 1, nr, nr + 1, 0, 0, 0, 0)
  2447.                 hbox = gtk.HBox()
  2448.                 if o.label:
  2449.                     a = gtk.Alignment(0.5, 0.5, 1, 1)
  2450.                     a.set_padding(0, 0, 0, 6)
  2451.                     a.add(o.label)
  2452.                     table.attach(a, 1, 2, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2453.                     table.attach(hbox, 2, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2454.                 else:
  2455.                     table.attach(hbox, 1, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  2456.                 hbox.pack_start(o.selector, False)
  2457.                 self.options[option.keyword] = o
  2458.                 o.selector.set_sensitive(editable)
  2459.                 if option.keyword == 'InputSlot':
  2460.                     self.option_inputslot = o
  2461.                     continue
  2462.                 if option.keyword == 'ManualFeed':
  2463.                     self.option_manualfeed = o
  2464.                     continue
  2465.             
  2466.         
  2467.         if not hasInstallableOptions:
  2468.             tab_nr = self.ntbkPrinter.page_num(self.swPInstallOptions)
  2469.             if tab_nr != -1:
  2470.                 self.ntbkPrinter.remove_page(tab_nr)
  2471.             
  2472.         
  2473.         for option in self.options.itervalues():
  2474.             conflicts = option.checkConflicts()
  2475.             if conflicts:
  2476.                 self.conflicts.add(option)
  2477.                 continue
  2478.         
  2479.         self.swPInstallOptions.show_all()
  2480.         self.swPOptions.show_all()
  2481.  
  2482.     
  2483.     def fillClassMembers(self, name, editable):
  2484.         printer = self.printers[name]
  2485.         self.btnClassAddMember.set_sensitive(editable)
  2486.         self.btnClassDelMember.set_sensitive(editable)
  2487.         tab_nr = self.ntbkPrinter.page_num(self.swPOptions)
  2488.         if tab_nr != -1:
  2489.             self.ntbkPrinter.remove_page(tab_nr)
  2490.         
  2491.         if self.ntbkPrinter.page_num(self.algnClassMembers) == -1:
  2492.             self.ntbkPrinter.insert_page(self.algnClassMembers, self.lblClassMembers, self.static_tabs)
  2493.         
  2494.         model_members = self.tvClassMembers.get_model()
  2495.         model_not_members = self.tvClassNotMembers.get_model()
  2496.         model_members.clear()
  2497.         model_not_members.clear()
  2498.         names = self.printers.keys()
  2499.         names.sort()
  2500.         for name in names:
  2501.             p = self.printers[name]
  2502.             if p is not printer:
  2503.                 if name in printer.class_members:
  2504.                     model_members.append((name,))
  2505.                 else:
  2506.                     model_not_members.append((name,))
  2507.             name in printer.class_members
  2508.         
  2509.  
  2510.     
  2511.     def on_btnClassAddMember_clicked(self, button):
  2512.         moveClassMembers(self.tvClassNotMembers, self.tvClassMembers)
  2513.         if getCurrentClassMembers(self.tvClassMembers) != self.printer.class_members:
  2514.             self.changed.add(self.tvClassMembers)
  2515.         else:
  2516.             self.changed.discard(self.tvClassMembers)
  2517.         self.setDataButtonState()
  2518.  
  2519.     
  2520.     def on_btnClassDelMember_clicked(self, button):
  2521.         moveClassMembers(self.tvClassMembers, self.tvClassNotMembers)
  2522.         if getCurrentClassMembers(self.tvClassMembers) != self.printer.class_members:
  2523.             self.changed.add(self.tvClassMembers)
  2524.         else:
  2525.             self.changed.discard(self.tvClassMembers)
  2526.         self.setDataButtonState()
  2527.  
  2528.     
  2529.     def on_quit_activate(self, widget, event = None):
  2530.         self.monitor.cleanup()
  2531.         while len(self.jobviewers) > 0:
  2532.             self.jobviewers[0].cleanup()
  2533.         del self.mainlist
  2534.         del self.printers
  2535.         gtk.main_quit()
  2536.  
  2537.     
  2538.     def is_rename_possible(self, name):
  2539.         jobs = self.printers[name].jobsQueued(limit = 1)
  2540.         if len(jobs) > 0:
  2541.             show_error_dialog(_('Cannot Rename'), _('There are queued jobs.'), parent = self.PrintersWindow)
  2542.             return False
  2543.         return True
  2544.  
  2545.     
  2546.     def rename_confirmed_by_user(self, name):
  2547.         '''
  2548.         Renaming deletes job history. So if we have some completed jobs,
  2549.         inform the user and let him confirm the renaming.
  2550.         '''
  2551.         preserved_jobs = self.printers[name].jobsPreserved(limit = 1)
  2552.         if len(preserved_jobs) > 0:
  2553.             dialog = gtk.MessageDialog(self.PrintersWindow, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK_CANCEL, _('Renaming will lose history'))
  2554.             dialog.format_secondary_text(_('Completed jobs will no longer be available for re-printing.'))
  2555.             result = dialog.run()
  2556.             dialog.destroy()
  2557.             if result == gtk.RESPONSE_CANCEL:
  2558.                 return False
  2559.         
  2560.         return True
  2561.  
  2562.     
  2563.     def on_rename_activate(self, UNUSED):
  2564.         tuple = self.dests_iconview.get_cursor()
  2565.         if tuple == None:
  2566.             return None
  2567.         (path, cell) = tuple
  2568.         if type(cell) != gtk.CellRendererText:
  2569.             cells = self.dests_iconview.get_cells()
  2570.             for cell in cells:
  2571.                 if type(cell) == gtk.CellRendererText:
  2572.                     break
  2573.                     continue
  2574.                 tuple == None
  2575.             
  2576.             if type(cell) != gtk.CellRendererText:
  2577.                 return None
  2578.         
  2579.         model = self.dests_iconview.get_model()
  2580.         iter = model.get_iter(path)
  2581.         name = unicode(model.get_value(iter, 2))
  2582.         if not self.is_rename_possible(name):
  2583.             return None
  2584.         if not self.rename_confirmed_by_user(name):
  2585.             return None
  2586.         cell.set_property('editable', True)
  2587.         self.dests_iconview.set_cursor(path, cell, start_editing = True)
  2588.         ids = []
  2589.         ids.append(cell.connect('edited', self.printer_name_edited))
  2590.         ids.append(cell.connect('editing-canceled', self.printer_name_edit_cancel))
  2591.         self.rename_sigids = ids
  2592.  
  2593.     
  2594.     def printer_name_edited(self, cell, path, newname):
  2595.         model = self.dests_iconview.get_model()
  2596.         iter = model.get_iter(path)
  2597.         name = unicode(model.get_value(iter, 2))
  2598.         debugprint('edited: %s -> %s' % (name, newname))
  2599.         
  2600.         try:
  2601.             self.rename_printer(name, newname)
  2602.         finally:
  2603.             cell.stop_editing(canceled = False)
  2604.             cell.set_property('editable', False)
  2605.             for id in self.rename_sigids:
  2606.                 cell.disconnect(id)
  2607.             
  2608.  
  2609.  
  2610.     
  2611.     def printer_name_edit_cancel(self, cell):
  2612.         debugprint('editing-canceled')
  2613.         cell.stop_editing(canceled = True)
  2614.         cell.set_property('editable', False)
  2615.         for id in self.rename_sigids:
  2616.             cell.disconnect(id)
  2617.         
  2618.  
  2619.     
  2620.     def rename_printer(self, old_name, new_name):
  2621.         if old_name == new_name:
  2622.             return None
  2623.         
  2624.         try:
  2625.             self.fillPrinterTab(old_name)
  2626.         except RuntimeError:
  2627.             old_name == new_name
  2628.             old_name == new_name
  2629.         except:
  2630.             old_name == new_name
  2631.  
  2632.         if not self.is_rename_possible(old_name):
  2633.             return None
  2634.         self.cups._begin_operation(_('renaming printer'))
  2635.         rejecting = self.printer.rejecting
  2636.         if not rejecting:
  2637.             
  2638.             try:
  2639.                 self.printer.setAccepting(False)
  2640.                 if not self.is_rename_possible(old_name):
  2641.                     self.printer.setAccepting(True)
  2642.                     self.cups._end_operation()
  2643.                     return None
  2644.             except cups.IPPError:
  2645.                 self.is_rename_possible(old_name)
  2646.                 (e, msg) = self.is_rename_possible(old_name)
  2647.                 old_name == new_name
  2648.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2649.                 self.cups._end_operation()
  2650.                 return None
  2651.             
  2652.  
  2653.         self.is_rename_possible(old_name)<EXCEPTION MATCH>cups.IPPError
  2654.         if self.copy_printer(new_name):
  2655.             self.monitor.update()
  2656.             if not rejecting:
  2657.                 
  2658.                 try:
  2659.                     self.printers[old_name].setAccepting(True)
  2660.                 except cups.HTTPError:
  2661.                     self.is_rename_possible(old_name)
  2662.                     (s,) = self.is_rename_possible(old_name)
  2663.                     self.is_rename_possible(old_name)
  2664.                     show_HTTP_Error(s, self.PrintersWindow)
  2665.                 except cups.IPPError:
  2666.                     self.is_rename_possible(old_name)
  2667.                     (e, msg) = self.is_rename_possible(old_name)
  2668.                     self.is_rename_possible(old_name)
  2669.                     show_IPP_Error(e, msg, self.PrintersWindow)
  2670.                 except:
  2671.                     self.is_rename_possible(old_name)<EXCEPTION MATCH>cups.HTTPError
  2672.                 
  2673.  
  2674.             self.is_rename_possible(old_name)
  2675.             self.cups._end_operation()
  2676.             return None
  2677.         if not rejecting:
  2678.             
  2679.             try:
  2680.                 self.printer.setAccepting(True)
  2681.             except cups.HTTPError:
  2682.                 self.copy_printer(new_name)
  2683.                 (s,) = self.copy_printer(new_name)
  2684.                 self.is_rename_possible(old_name)
  2685.                 show_HTTP_Error(s, self.PrintersWindow)
  2686.             except cups.IPPError:
  2687.                 self.copy_printer(new_name)
  2688.                 (e, msg) = self.copy_printer(new_name)
  2689.                 self.copy_printer(new_name)
  2690.                 show_IPP_Error(e, msg, self.PrintersWindow)
  2691.             except:
  2692.                 self.copy_printer(new_name)<EXCEPTION MATCH>cups.HTTPError
  2693.             
  2694.  
  2695.         self.copy_printer(new_name)
  2696.         
  2697.         try:
  2698.             self.cups.deletePrinter(old_name)
  2699.         except cups.HTTPError:
  2700.             None if self.default_printer == old_name else old_name == new_name
  2701.             (s,) = None if self.default_printer == old_name else old_name == new_name
  2702.             show_HTTP_Error(s, self.PrintersWindow)
  2703.         except cups.IPPError:
  2704.             (e, msg) = None
  2705.             show_IPP_Error(e, msg, self.PrintersWindow)
  2706.         except:
  2707.             None if self.default_printer == old_name else old_name == new_name
  2708.  
  2709.         self.cups._end_operation()
  2710.         
  2711.         def select_new_printer(model, path, iter):
  2712.             name = unicode(model.get_value(iter, 2))
  2713.             print name, new_name
  2714.             if name == new_name:
  2715.                 self.dests_iconview.select_path(path)
  2716.             
  2717.  
  2718.         self.populateList()
  2719.         model = self.dests_iconview.get_model()
  2720.         model.foreach(select_new_printer)
  2721.  
  2722.     
  2723.     def copy_printer(self, new_name):
  2724.         self.printer.name = new_name
  2725.         self.printer.class_members = []
  2726.         self.cups._begin_operation(_('copying printer'))
  2727.         ret = self.save_printer(self.printer, saveall = True, parent = self.PrintersWindow)
  2728.         self.cups._end_operation()
  2729.         return ret
  2730.  
  2731.     
  2732.     def on_copy_activate(self, UNUSED):
  2733.         iconview = self.dests_iconview
  2734.         paths = iconview.get_selected_items()
  2735.         model = self.dests_iconview.get_model()
  2736.         iter = model.get_iter(paths[0])
  2737.         name = unicode(model.get_value(iter, 2))
  2738.         self.entCopyName.set_text(name)
  2739.         self.NewPrinterName.set_transient_for(self.PrintersWindow)
  2740.         result = self.NewPrinterName.run()
  2741.         self.NewPrinterName.hide()
  2742.         if result == gtk.RESPONSE_CANCEL:
  2743.             return None
  2744.         
  2745.         try:
  2746.             self.fillPrinterTab(name)
  2747.         except RuntimeError:
  2748.             result == gtk.RESPONSE_CANCEL
  2749.             result == gtk.RESPONSE_CANCEL
  2750.         except:
  2751.             result == gtk.RESPONSE_CANCEL
  2752.  
  2753.         self.copy_printer(self.entCopyName.get_text())
  2754.         self.monitor.update()
  2755.  
  2756.     
  2757.     def on_entCopyName_changed(self, widget):
  2758.         text = unicode(widget.get_text())
  2759.         new_text = text
  2760.         new_text = new_text.replace('/', '')
  2761.         new_text = new_text.replace('#', '')
  2762.         new_text = new_text.replace(' ', '')
  2763.         if text != new_text:
  2764.             widget.set_text(new_text)
  2765.         
  2766.         self.btnCopyOk.set_sensitive(self.checkNPName(new_text))
  2767.  
  2768.     
  2769.     def on_delete_activate(self, UNUSED):
  2770.         if isinstance(self.current_groups_pane_item, StaticGroupItem):
  2771.             paths = self.dests_iconview.get_selected_items()
  2772.             model = self.dests_iconview.get_model()
  2773.             selected_names = []
  2774.             for path in paths:
  2775.                 selected_names.append(model[path][2])
  2776.             
  2777.             self.current_groups_pane_item.remove_queues(selected_names)
  2778.             self.populateList()
  2779.         else:
  2780.             self.delete_selected_printer_queues()
  2781.  
  2782.     
  2783.     def delete_selected_printer_queues(self):
  2784.         paths = self.dests_iconview.get_selected_items()
  2785.         model = self.dests_iconview.get_model()
  2786.         n = len(paths)
  2787.         if n == 1:
  2788.             iter = model.get_iter(paths[0])
  2789.             object = model.get_value(iter, 0)
  2790.             name = model.get_value(iter, 2)
  2791.             if object.is_class:
  2792.                 message_format = _("Really delete class '%s'?") % name
  2793.             else:
  2794.                 message_format = _("Really delete printer '%s'?") % name
  2795.         else:
  2796.             message_format = _('Really delete selected destinations?')
  2797.         dialog = gtk.MessageDialog(self.PrintersWindow, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, message_format)
  2798.         dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_DELETE, gtk.RESPONSE_ACCEPT)
  2799.         dialog.set_default_response(gtk.RESPONSE_REJECT)
  2800.         result = dialog.run()
  2801.         dialog.destroy()
  2802.         if result != gtk.RESPONSE_ACCEPT:
  2803.             return None
  2804.         
  2805.         try:
  2806.             for path in paths:
  2807.                 iter = model.get_iter(path)
  2808.                 name = model.get_value(iter, 2)
  2809.                 self.cups._begin_operation(_('deleting printer %s') % name)
  2810.                 name = unicode(name)
  2811.                 self.cups.deletePrinter(name)
  2812.                 self.cups._end_operation()
  2813.         except cups.IPPError:
  2814.             result != gtk.RESPONSE_ACCEPT
  2815.             (e, msg) = result != gtk.RESPONSE_ACCEPT
  2816.             self.cups._end_operation()
  2817.             show_IPP_Error(e, msg, self.PrintersWindow)
  2818.         except:
  2819.             result != gtk.RESPONSE_ACCEPT
  2820.  
  2821.         self.changed = set()
  2822.         self.monitor.update()
  2823.  
  2824.     
  2825.     def on_enabled_activate(self, toggle_action):
  2826.         if self.updating_widgets:
  2827.             return None
  2828.         enable = toggle_action.get_active()
  2829.         iconview = self.dests_iconview
  2830.         paths = iconview.get_selected_items()
  2831.         model = iconview.get_model()
  2832.         for path in paths:
  2833.             iter = model.get_iter(path)
  2834.             printer = model.get_value(iter, 0)
  2835.             name = unicode(model.get_value(iter, 2), 'utf-8')
  2836.             self.cups._begin_operation(_('modifying printer %s') % name)
  2837.             
  2838.             try:
  2839.                 printer.setEnabled(enable)
  2840.             except cups.IPPError:
  2841.                 self.updating_widgets
  2842.                 (e, m) = self.updating_widgets
  2843.                 errordialogs.show_IPP_Error(e, m, self.PrintersWindow)
  2844.                 self.cups._end_operation()
  2845.                 break
  2846.             except:
  2847.                 self.updating_widgets
  2848.  
  2849.             self.cups._end_operation()
  2850.         
  2851.         self.monitor.update()
  2852.  
  2853.     
  2854.     def on_shared_activate(self, menuitem):
  2855.         if self.updating_widgets:
  2856.             return None
  2857.         share = menuitem.get_active()
  2858.         iconview = self.dests_iconview
  2859.         paths = iconview.get_selected_items()
  2860.         model = iconview.get_model()
  2861.         success = False
  2862.         for path in paths:
  2863.             iter = model.get_iter(path)
  2864.             printer = model.get_value(iter, 0)
  2865.             self.cups._begin_operation(_('modifying printer %s') % printer.name)
  2866.             
  2867.             try:
  2868.                 printer.setShared(share)
  2869.                 success = True
  2870.             except cups.IPPError:
  2871.                 self.updating_widgets
  2872.                 (e, m) = self.updating_widgets
  2873.                 show_IPP_Error(e, m, self.PrintersWindow)
  2874.                 self.cups._end_operation()
  2875.                 break
  2876.             except:
  2877.                 self.updating_widgets
  2878.  
  2879.             self.cups._end_operation()
  2880.         
  2881.         if success and share:
  2882.             self.advise_publish()
  2883.         
  2884.         
  2885.         def deferred_refresh():
  2886.             self.populateList()
  2887.             return False
  2888.  
  2889.         gobject.idle_add(deferred_refresh)
  2890.  
  2891.     
  2892.     def advise_publish(self):
  2893.         if not self.server_is_publishing:
  2894.             show_info_dialog(_('Publish Shared Printers'), _("Shared printers are not available to other people unless the 'Publish shared printers' option is enabled in the server settings."), parent = self.PrintersWindow)
  2895.         
  2896.  
  2897.     
  2898.     def on_set_as_default_activate(self, UNUSED):
  2899.         iconview = self.dests_iconview
  2900.         paths = iconview.get_selected_items()
  2901.         model = iconview.get_model()
  2902.         iter = model.get_iter(paths[0])
  2903.         name = unicode(model.get_value(iter, 2))
  2904.         self.set_system_or_user_default_printer(name)
  2905.  
  2906.     
  2907.     def on_edit_activate(self, UNUSED):
  2908.         paths = self.dests_iconview.get_selected_items()
  2909.         self.dests_iconview_item_activated(self.dests_iconview, paths[0])
  2910.  
  2911.     
  2912.     def on_create_class_activate(self, UNUSED):
  2913.         paths = self.dests_iconview.get_selected_items()
  2914.         class_members = []
  2915.         model = self.dests_iconview.get_model()
  2916.         for path in paths:
  2917.             iter = model.get_iter(path)
  2918.             name = unicode(model.get_value(iter, 2), 'utf-8')
  2919.             class_members.append(name)
  2920.         
  2921.         self.newPrinterGUI.init('class')
  2922.         out_model = self.newPrinterGUI.tvNCNotMembers.get_model()
  2923.         in_model = self.newPrinterGUI.tvNCMembers.get_model()
  2924.         iter = out_model.get_iter_first()
  2925.         while iter != None:
  2926.             next = out_model.iter_next(iter)
  2927.             data = out_model.get(iter, 0)
  2928.             if data[0] in class_members:
  2929.                 in_model.append(data)
  2930.                 out_model.remove(iter)
  2931.             
  2932.             iter = next
  2933.  
  2934.     
  2935.     def on_view_print_queue_activate(self, UNUSED):
  2936.         paths = self.dests_iconview.get_selected_items()
  2937.         if len(paths):
  2938.             specific_dests = []
  2939.             model = self.dests_iconview.get_model()
  2940.             for path in paths:
  2941.                 iter = model.get_iter(path)
  2942.                 name = unicode(model.get_value(iter, 2), 'utf-8')
  2943.                 specific_dests.append(name)
  2944.             
  2945.             viewer = jobviewer.JobViewer(None, None, my_jobs = False, specific_dests = specific_dests, exit_handler = self.on_jobviewer_exit, parent = self.PrintersWindow)
  2946.         else:
  2947.             viewer = jobviewer.JobViewer(None, None, my_jobs = False, exit_handler = self.on_jobviewer_exit, parent = self.PrintersWindow)
  2948.         self.jobviewers.append(viewer)
  2949.  
  2950.     
  2951.     def on_jobviewer_exit(self, viewer):
  2952.         i = self.jobviewers.index(viewer)
  2953.         del self.jobviewers[i]
  2954.  
  2955.     
  2956.     def on_view_groups_activate(self, widget):
  2957.         if widget.get_active():
  2958.             if not self.groups_pane_visible:
  2959.                 self.view_area_vbox.remove(self.view_area_scrolledwindow)
  2960.                 self.view_area_hpaned.add2(self.view_area_scrolledwindow)
  2961.                 self.view_area_vbox.add(self.view_area_hpaned)
  2962.                 self.view_area_vbox.show_all()
  2963.                 self.groups_pane_visible = True
  2964.             
  2965.         elif self.groups_pane_visible:
  2966.             self.view_area_vbox.remove(self.view_area_hpaned)
  2967.             self.view_area_hpaned.remove(self.view_area_scrolledwindow)
  2968.             self.view_area_vbox.add(self.view_area_scrolledwindow)
  2969.             self.view_area_vbox.show_all()
  2970.             self.groups_pane_visible = False
  2971.         
  2972.  
  2973.     
  2974.     def on_view_discovered_printers_activate(self, UNUSED):
  2975.         self.populateList()
  2976.  
  2977.     
  2978.     def on_troubleshoot_activate(self, widget):
  2979.         if not self.__dict__.has_key('troubleshooter'):
  2980.             self.troubleshooter = troubleshoot.run(self.on_troubleshoot_quit)
  2981.         
  2982.  
  2983.     
  2984.     def on_troubleshoot_quit(self, troubleshooter):
  2985.         del self.troubleshooter
  2986.  
  2987.     
  2988.     def on_save_as_group_activate(self, UNUSED):
  2989.         model = self.dests_iconview.get_model()
  2990.         printer_queues = []
  2991.         for object in model:
  2992.             printer_queues.append(object[2])
  2993.         
  2994.         self.groups_pane.create_new_group(printer_queues, self.current_filter_text)
  2995.  
  2996.     
  2997.     def on_save_as_search_group_activate(self, UNUSED):
  2998.         criterion = None
  2999.         if self.current_filter_mode == 'filter-name':
  3000.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_NAME, value = self.current_filter_text)
  3001.         elif self.current_filter_mode == 'filter-description':
  3002.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_DESC, value = self.current_filter_text)
  3003.         elif self.current_filter_mode == 'filter-location':
  3004.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_LOCATION, value = self.current_filter_text)
  3005.         elif self.current_filter_mode == 'filter-manufacturer':
  3006.             criterion = SearchCriterion(subject = SearchCriterion.SUBJECT_MANUF, value = self.current_filter_text)
  3007.         else:
  3008.             nonfatalException()
  3009.             return None
  3010.         (self.current_filter_mode == 'filter-name').groups_pane.create_new_search_group(criterion, self.current_filter_text)
  3011.  
  3012.     
  3013.     def on_about_activate(self, widget):
  3014.         self.AboutDialog.set_transient_for(self.PrintersWindow)
  3015.         self.AboutDialog.run()
  3016.         self.AboutDialog.hide()
  3017.  
  3018.     
  3019.     def fillServerTab(self):
  3020.         self.changed = set()
  3021.         self.cups._begin_operation(_('fetching server settings'))
  3022.         
  3023.         try:
  3024.             self.server_settings = self.cups.adminGetServerSettings()
  3025.         except cups.IPPError:
  3026.             (e, m) = None
  3027.             show_IPP_Error(e, m, self.PrintersWindow)
  3028.             self.cups._end_operation()
  3029.             raise 
  3030.  
  3031.         self.cups._end_operation()
  3032.         for widget, setting in [
  3033.             (self.chkServerBrowse, cups.CUPS_SERVER_REMOTE_PRINTERS),
  3034.             (self.chkServerShare, cups.CUPS_SERVER_SHARE_PRINTERS),
  3035.             (self.chkServerShareAny, try_CUPS_SERVER_REMOTE_ANY),
  3036.             (self.chkServerRemoteAdmin, cups.CUPS_SERVER_REMOTE_ADMIN),
  3037.             (self.chkServerAllowCancelAll, cups.CUPS_SERVER_USER_CANCEL_ANY),
  3038.             (self.chkServerLogDebug, cups.CUPS_SERVER_DEBUG_LOGGING)]:
  3039.             widget.set_data('setting', setting)
  3040.             if self.server_settings.has_key(setting):
  3041.                 widget.set_active(int(self.server_settings[setting]))
  3042.                 widget.set_sensitive(True)
  3043.                 continue
  3044.             widget.set_active(False)
  3045.             widget.set_sensitive(False)
  3046.         
  3047.         self.setDataButtonState()
  3048.         
  3049.         try:
  3050.             flag = cups.CUPS_SERVER_SHARE_PRINTERS
  3051.             publishing = int(self.server_settings[flag])
  3052.             self.server_is_publishing = publishing
  3053.         except AttributeError:
  3054.             pass
  3055.  
  3056.         self.on_server_changed(self.chkServerShare)
  3057.  
  3058.     
  3059.     def on_server_changed(self, widget):
  3060.         setting = widget.get_data('setting')
  3061.         if self.server_settings.has_key(setting):
  3062.             if str(int(widget.get_active())) == self.server_settings[setting]:
  3063.                 self.changed.discard(widget)
  3064.             else:
  3065.                 self.changed.add(widget)
  3066.         
  3067.         sharing = self.chkServerShare.get_active()
  3068.         if sharing:
  3069.             pass
  3070.         self.chkServerShareAny.set_sensitive(self.server_settings.has_key(try_CUPS_SERVER_REMOTE_ANY))
  3071.         self.setDataButtonState()
  3072.  
  3073.     
  3074.     def save_serversettings(self):
  3075.         setting_dict = self.server_settings.copy()
  3076.         for widget, setting in [
  3077.             (self.chkServerBrowse, cups.CUPS_SERVER_REMOTE_PRINTERS),
  3078.             (self.chkServerShare, cups.CUPS_SERVER_SHARE_PRINTERS),
  3079.             (self.chkServerShareAny, try_CUPS_SERVER_REMOTE_ANY),
  3080.             (self.chkServerRemoteAdmin, cups.CUPS_SERVER_REMOTE_ADMIN),
  3081.             (self.chkServerAllowCancelAll, cups.CUPS_SERVER_USER_CANCEL_ANY),
  3082.             (self.chkServerLogDebug, cups.CUPS_SERVER_DEBUG_LOGGING)]:
  3083.             if not self.server_settings.has_key(setting):
  3084.                 continue
  3085.             
  3086.             setting_dict[setting] = str(int(widget.get_active()))
  3087.         
  3088.         self.cups._begin_operation(_('modifying server settings'))
  3089.         
  3090.         try:
  3091.             self.cups.adminSetServerSettings(setting_dict)
  3092.         except cups.IPPError:
  3093.             (e, m) = None
  3094.             show_IPP_Error(e, m, self.ServerSettingsDialog)
  3095.             self.cups._end_operation()
  3096.             return True
  3097.             except RuntimeError:
  3098.                 s = None
  3099.                 show_IPP_Error(None, s, self.ServerSettingsDialog)
  3100.                 self.cups._end_operation()
  3101.                 return True
  3102.             else:
  3103.                 self.cups._end_operation()
  3104.                 self.changed = set()
  3105.                 self.setDataButtonState()
  3106.                 old_setting = self.server_settings.get(cups.CUPS_SERVER_SHARE_PRINTERS, '0')
  3107.                 new_setting = setting_dict.get(cups.CUPS_SERVER_SHARE_PRINTERS, '0')
  3108.                 if 0 and old_setting == '0' and new_setting != '0':
  3109.                     show_info_dialog(_('Review Firewall'), _('You may need to adjust the firewall to allow network printing to this computer.') + '\n\n' + TEXT_start_firewall_tool, parent = self.ServerSettingsDialog)
  3110.                 
  3111.  
  3112.         time.sleep(1)
  3113.         self.reconnect()
  3114.         
  3115.         try:
  3116.             self.fillServerTab()
  3117.         except:
  3118.             nonfatalException()
  3119.  
  3120.  
  3121.     
  3122.     def on_problems_button_clicked(self, *args):
  3123.         if not self.__dict__.has_key('troubleshooter'):
  3124.             self.troubleshooter = troubleshoot.run(self.on_troubleshoot_quit, parent = self.ServerSettingsDialog)
  3125.         
  3126.  
  3127.     
  3128.     def on_new_printer_activate(self, widget):
  3129.         self.busy(self.PrintersWindow)
  3130.         self.newPrinterGUI.init('printer')
  3131.         self.ready(self.PrintersWindow)
  3132.  
  3133.     
  3134.     def on_autodetected_printer_without_driver(self, widget):
  3135.         self.busy(self.PrintersWindow)
  3136.         self.newPrinterGUI.init('printer_with_uri')
  3137.         self.ready(self.PrintersWindow)
  3138.  
  3139.     
  3140.     def on_new_class_activate(self, widget):
  3141.         self.newPrinterGUI.init('class')
  3142.  
  3143.     
  3144.     def on_btnSelectDevice_clicked(self, button):
  3145.         self.busy(self.PrintersWindow)
  3146.         self.newPrinterGUI.init('device')
  3147.         self.ready(self.PrintersWindow)
  3148.  
  3149.     
  3150.     def on_btnChangePPD_clicked(self, button):
  3151.         self.busy(self.PrintersWindow)
  3152.         self.newPrinterGUI.init('ppd')
  3153.         self.ready(self.PrintersWindow)
  3154.  
  3155.     
  3156.     def checkNPName(self, name):
  3157.         if not name:
  3158.             return False
  3159.         name = unicode(name.lower())
  3160.         for printer in self.printers.values():
  3161.             if not (printer.discovered) and printer.name.lower() == name:
  3162.                 return False
  3163.         
  3164.         return True
  3165.  
  3166.     
  3167.     def makeNameUnique(self, name):
  3168.         '''Make a suggested queue name valid and unique.'''
  3169.         name = name.replace(' ', '-')
  3170.         name = name.replace('/', '-')
  3171.         name = name.replace('#', '-')
  3172.         if not self.checkNPName(name):
  3173.             suffix = 2
  3174.             while not self.checkNPName(name + '-' + str(suffix)):
  3175.                 suffix += 1
  3176.                 if suffix == 100:
  3177.                     break
  3178.                     continue
  3179.             name += '-' + str(suffix)
  3180.         
  3181.         return name
  3182.  
  3183.     
  3184.     def printer_added_or_removed(self):
  3185.         gtk.gdk.threads_enter()
  3186.         self.populateList(prompt_allowed = False)
  3187.         gtk.gdk.threads_leave()
  3188.  
  3189.     
  3190.     def printer_added(self, mon, printer):
  3191.         monitor.Watcher.printer_added(self, mon, printer)
  3192.         self.printer_added_or_removed()
  3193.  
  3194.     
  3195.     def printer_event(self, mon, printer, eventname, event):
  3196.         monitor.Watcher.printer_event(self, mon, printer, eventname, event)
  3197.         
  3198.         def deferred_refresh():
  3199.             self.populateList()
  3200.             return False
  3201.  
  3202.         gtk.gdk.threads_enter()
  3203.         if self.printers.has_key(printer):
  3204.             self.printers[printer].update(**event)
  3205.             self.dests_iconview_selection_changed(self.dests_iconview)
  3206.             gobject.idle_add(deferred_refresh)
  3207.             if self.PrinterPropertiesDialog.get_property('visible'):
  3208.                 self.printer.getAttributes()
  3209.                 self.updatePrinterProperties()
  3210.             
  3211.         
  3212.         gtk.gdk.threads_leave()
  3213.  
  3214.     
  3215.     def printer_removed(self, mon, printer):
  3216.         monitor.Watcher.printer_removed(self, mon, printer)
  3217.         self.printer_added_or_removed()
  3218.  
  3219.     
  3220.     def state_reason_added(self, mon, reason):
  3221.         monitor.Watcher.state_reason_added(self, mon, reason)
  3222.         gtk.gdk.threads_enter()
  3223.         if self.PrinterPropertiesDialog.get_property('visible'):
  3224.             self.printer.getAttributes()
  3225.             self.updatePrinterProperties()
  3226.         
  3227.         gtk.gdk.threads_leave()
  3228.  
  3229.     
  3230.     def state_reason_removed(self, mon, reason):
  3231.         monitor.Watcher.state_reason_removed(self, mon, reason)
  3232.         gtk.gdk.threads_enter()
  3233.         if self.PrinterPropertiesDialog.get_property('visible'):
  3234.             self.printer.getAttributes()
  3235.             self.updatePrinterProperties()
  3236.         
  3237.         gtk.gdk.threads_leave()
  3238.  
  3239.     
  3240.     def cups_connection_error(self, mon):
  3241.         monitor.Watcher.cups_connection_error(self, mon)
  3242.         
  3243.         try:
  3244.             self.cups.getClasses()
  3245.         except:
  3246.             self.cups = None
  3247.             gtk.gdk.threads_enter()
  3248.             self.setConnected()
  3249.             self.populateList(prompt_allowed = False)
  3250.             gtk.gdk.threads_leave()
  3251.  
  3252.  
  3253.  
  3254.  
  3255. class NewPrinterGUI(GtkGUI):
  3256.     new_printer_device_tabs = {
  3257.         'parallel': 0,
  3258.         'usb': 0,
  3259.         'bluetooth': 0,
  3260.         'hal': 0,
  3261.         'beh': 0,
  3262.         'hp': 0,
  3263.         'hpfax': 0,
  3264.         'dnssd': 0,
  3265.         'socket': 2,
  3266.         'ipp': 3,
  3267.         'http': 3,
  3268.         'https': 3,
  3269.         'lpd': 4,
  3270.         'scsi': 5,
  3271.         'serial': 6,
  3272.         'smb': 7,
  3273.         'network': 8 }
  3274.     DOWNLOADABLE_ONLYPPD = True
  3275.     HP_PLUGIN_SUPPORT = True
  3276.     
  3277.     def __init__(self, mainapp):
  3278.         self.mainapp = mainapp
  3279.         self.language = mainapp.language
  3280.         self.options = { }
  3281.         self.changed = set()
  3282.         self.conflicts = set()
  3283.         self.device = None
  3284.         self.ppd = None
  3285.         self.remotecupsqueue = False
  3286.         self.exactdrivermatch = False
  3287.         self.installable_options = False
  3288.         self.jockey_installed_files = []
  3289.         self.jockey_lock = thread.allocate_lock()
  3290.         self.ppds_lock = thread.allocate_lock()
  3291.         self.ppds_queried = False
  3292.         self.drivers_lock = thread.allocate_lock()
  3293.         self.getWidgets({
  3294.             'NewPrinterWindow': [
  3295.                 'NewPrinterWindow',
  3296.                 'ntbkNewPrinter',
  3297.                 'btnNPBack',
  3298.                 'btnNPForward',
  3299.                 'btnNPApply',
  3300.                 'imgProcessWorking',
  3301.                 'entNPName',
  3302.                 'entNPDescription',
  3303.                 'entNPLocation',
  3304.                 'tvNPDevices',
  3305.                 'ntbkNPType',
  3306.                 'lblNPDeviceDescription',
  3307.                 'expNPDeviceURIs',
  3308.                 'tvNPDeviceURIs',
  3309.                 'cmbNPTSerialBaud',
  3310.                 'cmbNPTSerialParity',
  3311.                 'cmbNPTSerialBits',
  3312.                 'cmbNPTSerialFlow',
  3313.                 'btnNPTLpdProbe',
  3314.                 'cmbentNPTLpdHost',
  3315.                 'cmbentNPTLpdQueue',
  3316.                 'entNPTIPPHostname',
  3317.                 'lblIPPURI',
  3318.                 'entNPTIPPQueuename',
  3319.                 'btnIPPVerify',
  3320.                 'entNPTDirectJetHostname',
  3321.                 'entNPTDirectJetPort',
  3322.                 'entSMBURI',
  3323.                 'btnSMBBrowse',
  3324.                 'tblSMBAuth',
  3325.                 'rbtnSMBAuthPrompt',
  3326.                 'rbtnSMBAuthSet',
  3327.                 'entSMBUsername',
  3328.                 'entSMBPassword',
  3329.                 'btnSMBVerify',
  3330.                 'entNPTNetworkHostname',
  3331.                 'btnNetworkFind',
  3332.                 'lblNetworkFindSearching',
  3333.                 'lblNetworkFindNotFound',
  3334.                 'entNPTDevice',
  3335.                 'tvNCMembers',
  3336.                 'tvNCNotMembers',
  3337.                 'btnNCAddMember',
  3338.                 'btnNCDelMember',
  3339.                 'ntbkPPDSource',
  3340.                 'rbtnNPPPD',
  3341.                 'tvNPMakes',
  3342.                 'rbtnNPFoomatic',
  3343.                 'filechooserPPD',
  3344.                 'rbtnNPDownloadableDriverSearch',
  3345.                 'entNPDownloadableDriverSearch',
  3346.                 'btnNPDownloadableDriverSearch',
  3347.                 'cmbNPDownloadableDriverFoundPrinters',
  3348.                 'tvNPModels',
  3349.                 'tvNPDrivers',
  3350.                 'rbtnChangePPDasIs',
  3351.                 'rbtnChangePPDKeepSettings',
  3352.                 'scrNPInstallableOptions',
  3353.                 'vbNPInstallOptions',
  3354.                 'tvNPDownloadableDrivers',
  3355.                 'ntbkNPDownloadableDriverProperties',
  3356.                 'lblNPDownloadableDriverSupplier',
  3357.                 'cbNPDownloadableDriverSupplierVendor',
  3358.                 'lblNPDownloadableDriverLicense',
  3359.                 'cbNPDownloadableDriverLicensePatents',
  3360.                 'cbNPDownloadableDriverLicenseFree',
  3361.                 'lblNPDownloadableDriverDescription',
  3362.                 'lblNPDownloadableDriverSupportContacts',
  3363.                 'hsDownloadableDriverPerfText',
  3364.                 'hsDownloadableDriverPerfLineArt',
  3365.                 'hsDownloadableDriverPerfGraphics',
  3366.                 'hsDownloadableDriverPerfPhoto',
  3367.                 'lblDownloadableDriverPerfTextUnknown',
  3368.                 'lblDownloadableDriverPerfLineArtUnknown',
  3369.                 'lblDownloadableDriverPerfGraphicsUnknown',
  3370.                 'lblDownloadableDriverPerfPhotoUnknown',
  3371.                 'frmNPDownloadableDriverLicenseTerms',
  3372.                 'tvNPDownloadableDriverLicense',
  3373.                 'rbtnNPDownloadLicenseYes',
  3374.                 'rbtnNPDownloadLicenseNo'],
  3375.             'WaitWindow': [
  3376.                 'WaitWindow',
  3377.                 'lblWait'],
  3378.             'SMBBrowseDialog': [
  3379.                 'SMBBrowseDialog',
  3380.                 'tvSMBBrowser',
  3381.                 'btnSMBBrowseOk'],
  3382.             'InstallDialog': [
  3383.                 'InstallDialog',
  3384.                 'lblInstall'] })
  3385.         for dialog in [
  3386.             self.SMBBrowseDialog]:
  3387.             dialog.connect('delete-event', on_delete_just_hide)
  3388.         
  3389.         self.busy = mainapp.busy
  3390.         self.ready = mainapp.ready
  3391.         gtk_label_autowrap.set_autowrap(self.NewPrinterWindow)
  3392.         self.ntbkNewPrinter.set_show_tabs(False)
  3393.         self.ntbkPPDSource.set_show_tabs(False)
  3394.         self.ntbkNPType.set_show_tabs(False)
  3395.         self.ntbkNPDownloadableDriverProperties.set_show_tabs(False)
  3396.         self.spinner = gtkspinner.Spinner(self.imgProcessWorking)
  3397.         self.openprinting = cupshelpers.openprinting.OpenPrinting()
  3398.         self.openprinting_query_handle = None
  3399.         combobox = self.cmbNPDownloadableDriverFoundPrinters
  3400.         cell = gtk.CellRendererText()
  3401.         combobox.pack_start(cell, True)
  3402.         combobox.add_attribute(cell, 'text', 0)
  3403.         if self.DOWNLOADABLE_ONLYPPD:
  3404.             for widget in [
  3405.                 self.cbNPDownloadableDriverLicenseFree,
  3406.                 self.cbNPDownloadableDriverLicensePatents]:
  3407.                 widget.hide()
  3408.             
  3409.         
  3410.         
  3411.         def protect_toggle(toggle_widget):
  3412.             active = toggle_widget.get_data('protect_active')
  3413.             if active != None:
  3414.                 toggle_widget.set_active(active)
  3415.             
  3416.  
  3417.         for widget in [
  3418.             self.cbNPDownloadableDriverSupplierVendor,
  3419.             self.cbNPDownloadableDriverLicenseFree,
  3420.             self.cbNPDownloadableDriverLicensePatents]:
  3421.             widget.connect('clicked', protect_toggle)
  3422.         
  3423.         for widget in [
  3424.             self.hsDownloadableDriverPerfText,
  3425.             self.hsDownloadableDriverPerfLineArt,
  3426.             self.hsDownloadableDriverPerfGraphics,
  3427.             self.hsDownloadableDriverPerfPhoto]:
  3428.             widget.connect('change-value', (lambda x, y, z: True))
  3429.         
  3430.         slct = self.tvNPDevices.get_selection()
  3431.         slct.set_select_function(self.device_select_function)
  3432.         self.tvNPDevices.set_row_separator_func(self.device_row_separator_fn)
  3433.         self.tvNPDevices.connect('row-activated', self.device_row_activated)
  3434.         self.expNPDeviceURIs.connect('notify::expanded', self.on_expNPDeviceURIs_expanded)
  3435.         self.smb_store = gtk.TreeStore(gobject.TYPE_PYOBJECT)
  3436.         self.btnSMBBrowse.set_sensitive(PYSMB_AVAILABLE)
  3437.         if not PYSMB_AVAILABLE:
  3438.             self.btnSMBBrowse.set_tooltip_text(_('Browsing not available (pysmbc not installed)'))
  3439.         
  3440.         self.tvSMBBrowser.set_model(self.smb_store)
  3441.         col = gtk.TreeViewColumn(_('Share'))
  3442.         cell = gtk.CellRendererText()
  3443.         col.pack_start(cell, False)
  3444.         col.set_cell_data_func(cell, self.smbbrowser_cell_share)
  3445.         self.tvSMBBrowser.append_column(col)
  3446.         col = gtk.TreeViewColumn(_('Comment'))
  3447.         cell = gtk.CellRendererText()
  3448.         col.pack_start(cell, False)
  3449.         col.set_cell_data_func(cell, self.smbbrowser_cell_comment)
  3450.         self.tvSMBBrowser.append_column(col)
  3451.         slct = self.tvSMBBrowser.get_selection()
  3452.         slct.set_select_function(self.smb_select_function)
  3453.         self.SMBBrowseDialog.set_transient_for(self.NewPrinterWindow)
  3454.         self.tvNPDrivers.set_has_tooltip(True)
  3455.         self.tvNPDrivers.connect('query-tooltip', self.on_NPDrivers_query_tooltip)
  3456.         ppd_filter = gtk.FileFilter()
  3457.         ppd_filter.set_name(_('PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *.PPD.GZ)'))
  3458.         ppd_filter.add_pattern('*.ppd')
  3459.         ppd_filter.add_pattern('*.PPD')
  3460.         ppd_filter.add_pattern('*.ppd.gz')
  3461.         ppd_filter.add_pattern('*.PPD.gz')
  3462.         ppd_filter.add_pattern('*.PPD.GZ')
  3463.         self.filechooserPPD.add_filter(ppd_filter)
  3464.         ppd_filter = gtk.FileFilter()
  3465.         ppd_filter.set_name(_('All files (*)'))
  3466.         ppd_filter.add_pattern('*')
  3467.         self.filechooserPPD.add_filter(ppd_filter)
  3468.  
  3469.     
  3470.     def show_IPP_Error(self, exception, message):
  3471.         return show_IPP_Error(exception, message, parent = self.NewPrinterWindow)
  3472.  
  3473.     
  3474.     def option_changed(self, option):
  3475.         if option.is_changed():
  3476.             self.changed.add(option)
  3477.         else:
  3478.             self.changed.discard(option)
  3479.         if option.conflicts:
  3480.             self.conflicts.add(option)
  3481.         else:
  3482.             self.conflicts.discard(option)
  3483.         self.setDataButtonState()
  3484.  
  3485.     
  3486.     def setDataButtonState(self):
  3487.         self.btnNPForward.set_sensitive(not bool(self.conflicts))
  3488.  
  3489.     
  3490.     def init(self, dialog_mode):
  3491.         self.dialog_mode = dialog_mode
  3492.         self.options = { }
  3493.         self.changed = set()
  3494.         self.conflicts = set()
  3495.         combobox = self.cmbNPDownloadableDriverFoundPrinters
  3496.         combobox.set_model(gtk.ListStore(str, str))
  3497.         self.entNPDownloadableDriverSearch.set_text('')
  3498.         button = self.btnNPDownloadableDriverSearch
  3499.         label = button.get_children()[0].get_children()[0].get_children()[1]
  3500.         self.btnNPDownloadableDriverSearch_label = label
  3501.         label.set_text(_('Search'))
  3502.         if self.dialog_mode in ('printer', 'printer_with_uri', 'class'):
  3503.             if self.dialog_mode == 'class':
  3504.                 name_proto = 'class'
  3505.             else:
  3506.                 name_proto = 'printer'
  3507.             self.entNPName.set_text(self.mainapp.makeNameUnique(name_proto))
  3508.             self.entNPName.grab_focus()
  3509.             for widget in [
  3510.                 self.entNPLocation,
  3511.                 self.entNPDescription,
  3512.                 self.entSMBURI,
  3513.                 self.entSMBUsername,
  3514.                 self.entSMBPassword]:
  3515.                 widget.set_text('')
  3516.             
  3517.         
  3518.         if self.dialog_mode == 'printer_with_uri':
  3519.             device_dict = { }
  3520.             self.device = cupshelpers.Device(self.mainapp.device_uri, **device_dict)
  3521.         
  3522.         self.entNPTDirectJetPort.set_text('9100')
  3523.         self.rbtnSMBAuthPrompt.set_active(True)
  3524.         if self.dialog_mode == 'printer':
  3525.             self.NewPrinterWindow.set_title(_('New Printer'))
  3526.             self.ntbkNewPrinter.set_current_page(1)
  3527.             self.fillDeviceTab()
  3528.             self.rbtnNPFoomatic.set_active(True)
  3529.             self.on_rbtnNPFoomatic_toggled(self.rbtnNPFoomatic)
  3530.             self.new_printer_PPDs_loaded = False
  3531.             self.queryPPDs()
  3532.         elif self.dialog_mode == 'class':
  3533.             self.NewPrinterWindow.set_title(_('New Class'))
  3534.             self.fillNewClassMembers()
  3535.             self.ntbkNewPrinter.set_current_page(0)
  3536.         elif self.dialog_mode == 'device':
  3537.             self.NewPrinterWindow.set_title(_('Change Device URI'))
  3538.             self.ntbkNewPrinter.set_current_page(1)
  3539.             self.fillDeviceTab(self.mainapp.printer.device_uri)
  3540.         elif self.dialog_mode == 'ppd' or self.dialog_mode == 'printer_with_uri':
  3541.             if self.dialog_mode == 'ppd':
  3542.                 self.NewPrinterWindow.set_title(_('Change Driver'))
  3543.             else:
  3544.                 self.NewPrinterWindow.set_title(_('New Printer'))
  3545.             self.ntbkNewPrinter.set_current_page(2)
  3546.             self.rbtnNPFoomatic.set_active(True)
  3547.             self.on_rbtnNPFoomatic_toggled(self.rbtnNPFoomatic)
  3548.             self.rbtnChangePPDKeepSettings.set_active(True)
  3549.             self.auto_model = ''
  3550.             ppd = self.mainapp.ppd
  3551.             devid = self.mainapp.devid
  3552.             if devid != '':
  3553.                 
  3554.                 try:
  3555.                     devid_dict = cupshelpers.parseDeviceID(devid)
  3556.                     self.loadPPDs()
  3557.                     reloaded = 0
  3558.                     while reloaded < 2:
  3559.                         (status, ppdname) = self.ppds.getPPDNameFromDeviceID(devid_dict['MFG'], devid_dict['MDL'], devid_dict['DES'], devid_dict['CMD'], uri, self.jockey_installed_files)
  3560.                         if status != self.ppds.STATUS_SUCCESS and reloaded == 0:
  3561.                             
  3562.                             try:
  3563.                                 if self.fetchJockeyDriver():
  3564.                                     
  3565.                                     try:
  3566.                                         self.dropPPDs()
  3567.                                         self.loadPPDs()
  3568.                                         reloaded = 1
  3569.                                     reloaded = 2
  3570.  
  3571.                                 else:
  3572.                                     reloaded = 2
  3573.                             reloaded = 2
  3574.  
  3575.                             continue
  3576.                         reloaded = 2
  3577.                     if ppdname:
  3578.                         ppddict = self.ppds.getInfoFromPPDName(ppdname)
  3579.                         make_model = ppddict['ppd-make-and-model']
  3580.                         (self.auto_make, self.auto_model) = cupshelpers.ppds.ppdMakeModelSplit(make_model)
  3581.                         if status == self.ppds.STATUS_SUCCESS and self.dialog_mode != 'ppd':
  3582.                             self.exactdrivermatch = True
  3583.                             self.fillMakeList()
  3584.                             self.ntbkNewPrinter.set_current_page(6)
  3585.                             self.nextNPTab(step = 0)
  3586.                         else:
  3587.                             self.exactdrivermatch = False
  3588.                     else:
  3589.                         self.auto_make = devid_dict['MFG']
  3590.                         self.auto_model = devid_dict['MDL']
  3591.                 except:
  3592.                     None if self.dialog_mode == 'ppd' else self.install_hplip_plugin(uri)
  3593.                     self.auto_make = devid_dict['MFG']
  3594.                     self.auto_model = devid_dict['MDL']
  3595.  
  3596.                 if not (self.device) or not (self.device.id):
  3597.                     self.device.id = devid
  3598.                     self.device.id_dict = cupshelpers.parseDeviceID(self.device.id)
  3599.                 
  3600.                 self.mainapp.devid = ''
  3601.             elif ppd:
  3602.                 attr = ppd.findAttr('Manufacturer')
  3603.                 if attr:
  3604.                     mfr = attr.value
  3605.                 else:
  3606.                     mfr = ''
  3607.                 makeandmodel = mfr
  3608.                 attr = ppd.findAttr('ModelName')
  3609.                 if not attr:
  3610.                     attr = ppd.findAttr('ShortNickName')
  3611.                 
  3612.                 if not attr:
  3613.                     attr = ppd.findAttr('NickName')
  3614.                 
  3615.                 if attr:
  3616.                     if attr.value.startswith(mfr):
  3617.                         makeandmodel = attr.value
  3618.                     else:
  3619.                         makeandmodel += ' ' + attr.value
  3620.                 else:
  3621.                     makeandmodel = ''
  3622.                 (self.auto_make, self.auto_model) = cupshelpers.ppds.ppdMakeModelSplit(makeandmodel)
  3623.             else:
  3624.                 self.auto_make = 'Raw'
  3625.                 self.auto_model = 'Queue'
  3626.             
  3627.             try:
  3628.                 if self.dialog_mode == 'ppd':
  3629.                     parent = self.mainapp.PrinterPropertiesDialog
  3630.                 else:
  3631.                     parent = self.NewPrinterWindow
  3632.                 self.loadPPDs(parent = parent)
  3633.             except cups.IPPError:
  3634.                 None if self.dialog_mode == 'ppd' else self.install_hplip_plugin(uri)
  3635.                 (e, m) = None if self.dialog_mode == 'ppd' else self.install_hplip_plugin(uri)
  3636.                 show_IPP_Error(e, m, parent = self.mainapp.PrintersWindow)
  3637.                 return None
  3638.                 return None
  3639.  
  3640.             self.fillMakeList()
  3641.         
  3642.         self.setNPButtons()
  3643.         self.NewPrinterWindow.show()
  3644.  
  3645.     
  3646.     def queryJockeyDriver(self):
  3647.         debugprint('queryJockeyDriver')
  3648.         if not self.jockey_lock.acquire(0):
  3649.             debugprint('queryJockeyDriver: in progress')
  3650.             return None
  3651.         debugprint('Lock acquired for Jockey driver thread')
  3652.         devid = ''
  3653.         
  3654.         try:
  3655.             devid = self.device.id
  3656.         except:
  3657.             self.jockey_lock.acquire(0)
  3658.  
  3659.         if devid == '':
  3660.             self.jockey_lock.release()
  3661.             return None
  3662.         thread.start_new_thread(self.getJockeyDriver_thread, (devid,))
  3663.         debugprint('Jockey driver thread started')
  3664.  
  3665.     
  3666.     def getJockeyDriver_thread(self, id):
  3667.         debugprint('Requesting driver from Jockey: %s' % id)
  3668.         self.jockey_driver_result = False
  3669.         self.jockey_installed_files = []
  3670.         
  3671.         try:
  3672.             bus = dbus.SessionBus()
  3673.             obj = bus.get_object('com.ubuntu.DeviceDriver', '/GUI')
  3674.             jockeyloader = dbus.Interface(obj, 'com.ubuntu.DeviceDriver')
  3675.             (result, installedfiles) = jockeyloader.search_driver('printer_deviceid:%s' % id, timeout = 999999)
  3676.             self.jockey_driver_result = result
  3677.             self.jockey_installed_files = installedfiles
  3678.             if result:
  3679.                 debugprint('New driver downloaded and installed')
  3680.             else:
  3681.                 debugprint('No new driver found or download rejected')
  3682.         except dbus.DBusException:
  3683.             e = None
  3684.             self.jockey_driver_result = e
  3685.             debugprint(self.jockey_driver_result)
  3686.         except Exception:
  3687.             e = None
  3688.             nonfatalException()
  3689.             self.jockey_driver_result = e
  3690.             debugprint('Non-D-Bus error on Jockey call: %s' % e)
  3691.  
  3692.         debugprint('Releasing Jockey driver lock')
  3693.         self.jockey_lock.release()
  3694.  
  3695.     
  3696.     def fetchJockeyDriver(self, parent = None):
  3697.         debugprint('fetchJockeyDriver')
  3698.         self.queryJockeyDriver()
  3699.         time.sleep(0.01)
  3700.         waiting = False
  3701.         while self.jockey_lock.locked():
  3702.             if not waiting:
  3703.                 waiting = True
  3704.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for downloadable drivers'))
  3705.                 if not parent:
  3706.                     parent = self.NewPrinterWindow
  3707.                 
  3708.                 self.WaitWindow.set_transient_for(parent)
  3709.                 self.WaitWindow.show()
  3710.                 self.busy(self.WaitWindow)
  3711.             
  3712.             if self.mainapp.cups == None:
  3713.                 debugprint('CUPS connection lost, reconnecting ...')
  3714.                 
  3715.                 try:
  3716.                     self.mainapp.cups = authconn.Connection(self.mainapp.PrintersWindow)
  3717.                     self.mainapp.setConnected()
  3718.                     debugprint('Reconnected')
  3719.                     self.mainapp.populateList()
  3720.                 except RuntimeError:
  3721.                     debugprint('Reconnection failed')
  3722.                 except:
  3723.                     None<EXCEPTION MATCH>RuntimeError
  3724.                 
  3725.  
  3726.             None<EXCEPTION MATCH>RuntimeError
  3727.             while gtk.events_pending():
  3728.                 gtk.main_iteration()
  3729.             time.sleep(0.1)
  3730.         if waiting:
  3731.             self.WaitWindow.hide()
  3732.         
  3733.         debugprint('Driver download request finished')
  3734.         result = self.jockey_driver_result
  3735.         if isinstance(result, Exception):
  3736.             raise result
  3737.         isinstance(result, Exception)
  3738.         return result
  3739.  
  3740.     
  3741.     def queryPPDs(self):
  3742.         debugprint('queryPPDs')
  3743.         if not self.ppds_lock.acquire(0):
  3744.             debugprint('queryPPDs: in progress')
  3745.             return None
  3746.         debugprint('Lock acquired for PPDs thread')
  3747.         self.ppds_queried = True
  3748.         thread.start_new_thread(self.getPPDs_thread, (self.language[0],))
  3749.         debugprint('PPDs thread started')
  3750.  
  3751.     
  3752.     def getPPDs_thread(self, language):
  3753.         
  3754.         try:
  3755.             debugprint('Connecting (PPDs)')
  3756.             cups.setUser(self.mainapp.connect_user)
  3757.             cups.setPasswordCB((lambda x: ''))
  3758.             c = cups.Connection(host = self.mainapp.connect_server, encryption = self.mainapp.connect_encrypt)
  3759.             debugprint('Fetching PPDs')
  3760.             ppds_dict = c.getPPDs()
  3761.             self.ppds_result = cupshelpers.ppds.PPDs(ppds_dict, language = language)
  3762.             debugprint('Closing connection (PPDs)')
  3763.             del c
  3764.         except cups.IPPError:
  3765.             (e, msg) = None
  3766.             self.ppds_result = cups.IPPError(e, msg)
  3767.         except Exception:
  3768.             e = None
  3769.             nonfatalException()
  3770.             self.ppds_result = e
  3771.  
  3772.         debugprint('Releasing PPDs lock')
  3773.         self.ppds_lock.release()
  3774.  
  3775.     
  3776.     def fetchPPDs(self, parent = None):
  3777.         debugprint('fetchPPDs')
  3778.         if not self.ppds_queried:
  3779.             self.queryPPDs()
  3780.         
  3781.         waiting = False
  3782.         while self.ppds_lock.locked():
  3783.             if not waiting:
  3784.                 waiting = True
  3785.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for drivers'))
  3786.                 if not parent:
  3787.                     parent = self.NewPrinterWindow
  3788.                 
  3789.                 self.WaitWindow.set_transient_for(parent)
  3790.                 self.WaitWindow.show()
  3791.                 self.busy(self.WaitWindow)
  3792.             
  3793.             while gtk.events_pending():
  3794.                 gtk.main_iteration()
  3795.             time.sleep(0.1)
  3796.         if waiting:
  3797.             self.WaitWindow.hide()
  3798.         
  3799.         debugprint('Got PPDs')
  3800.         self.ppds_queried = False
  3801.         result = self.ppds_result
  3802.         if isinstance(result, Exception):
  3803.             raise result
  3804.         isinstance(result, Exception)
  3805.         return result
  3806.  
  3807.     
  3808.     def loadPPDs(self, parent = None):
  3809.         
  3810.         try:
  3811.             return self.ppds
  3812.         except:
  3813.             self.ppds = self.fetchPPDs(parent = parent)
  3814.             return self.ppds
  3815.  
  3816.  
  3817.     
  3818.     def dropPPDs(self):
  3819.         
  3820.         try:
  3821.             del self.ppds
  3822.         except:
  3823.             pass
  3824.  
  3825.  
  3826.     
  3827.     def fillNewClassMembers(self):
  3828.         model = self.tvNCMembers.get_model()
  3829.         model.clear()
  3830.         model = self.tvNCNotMembers.get_model()
  3831.         model.clear()
  3832.         for printer in self.mainapp.printers.itervalues():
  3833.             model.append((printer.name,))
  3834.         
  3835.  
  3836.     
  3837.     def on_btnNCAddMember_clicked(self, button):
  3838.         moveClassMembers(self.tvNCNotMembers, self.tvNCMembers)
  3839.         self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  3840.         button.set_sensitive(False)
  3841.  
  3842.     
  3843.     def on_btnNCDelMember_clicked(self, button):
  3844.         moveClassMembers(self.tvNCMembers, self.tvNCNotMembers)
  3845.         self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  3846.         button.set_sensitive(False)
  3847.  
  3848.     
  3849.     def on_tvNCMembers_cursor_changed(self, widget):
  3850.         selection = widget.get_selection()
  3851.         (model_from, rows) = selection.get_selected_rows()
  3852.         self.btnNCDelMember.set_sensitive(rows != [])
  3853.  
  3854.     
  3855.     def on_tvNCNotMembers_cursor_changed(self, widget):
  3856.         selection = widget.get_selection()
  3857.         (model_from, rows) = selection.get_selected_rows()
  3858.         self.btnNCAddMember.set_sensitive(rows != [])
  3859.  
  3860.     
  3861.     def on_NPCancel(self, widget, event = None):
  3862.         self.NewPrinterWindow.hide()
  3863.         if self.openprinting_query_handle != None:
  3864.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  3865.             self.openprinting_query_handle = None
  3866.         
  3867.         return True
  3868.  
  3869.     
  3870.     def on_btnNPBack_clicked(self, widget):
  3871.         self.nextNPTab(-1)
  3872.  
  3873.     
  3874.     def on_btnNPForward_clicked(self, widget):
  3875.         self.nextNPTab()
  3876.  
  3877.     
  3878.     def nextNPTab(self, step = 1):
  3879.         page_nr = self.ntbkNewPrinter.get_current_page()
  3880.         if self.dialog_mode == 'class':
  3881.             order = [
  3882.                 0,
  3883.                 4,
  3884.                 5]
  3885.         elif self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri':
  3886.             self.busy(self.NewPrinterWindow)
  3887.             if page_nr == 1:
  3888.                 (self.auto_make, self.auto_model) = (None, None)
  3889.                 self.device.uri = self.getDeviceURI()
  3890.                 if not self.install_hplip_plugin(self.device.uri):
  3891.                     self.on_NPCancel(None)
  3892.                     return None
  3893.                 uri = self.device.uri
  3894.                 if uri and uri.startswith('smb://'):
  3895.                     uri = SMBURI(uri = uri[6:]).sanitize_uri()
  3896.                 
  3897.                 self.remotecupsqueue = None
  3898.                 res = re.search('ipp://(\\S+(:\\d+|))/printers/(\\S+)', uri)
  3899.                 if res:
  3900.                     resg = res.groups()
  3901.                     
  3902.                     try:
  3903.                         conn = httplib.HTTPConnection(resg[0])
  3904.                         conn.request('GET', '/printers/%s.ppd' % resg[2])
  3905.                         resp = conn.getresponse()
  3906.                         if resp.status == 200:
  3907.                             self.remotecupsqueue = resg[2]
  3908.                     except:
  3909.                         pass
  3910.  
  3911.                     
  3912.                     try:
  3913.                         if len(resg[1]) > 0:
  3914.                             port = int(resg[1])
  3915.                         else:
  3916.                             port = 631
  3917.                         encryption = cups.HTTP_ENCRYPT_IF_REQUESTED
  3918.                         c = cups.Connection(host = resg[0], port = port, encryption = encryption)
  3919.                         r = [
  3920.                             'printer-info',
  3921.                             'printer-location']
  3922.                         attrs = c.getPrinterAttributes(uri = uri, requested_attributes = r)
  3923.                         info = attrs.get('printer-info', '')
  3924.                         location = attrs.get('printer-location', '')
  3925.                         if len(info) > 0:
  3926.                             self.entNPDescription.set_text(info)
  3927.                         
  3928.                         if len(location) > 0:
  3929.                             self.entNPLocation.set_text(location)
  3930.                     except RuntimeError:
  3931.                         pass
  3932.                     except:
  3933.                         None<EXCEPTION MATCH>RuntimeError
  3934.                         nonfatalException()
  3935.                     
  3936.  
  3937.                 None<EXCEPTION MATCH>RuntimeError
  3938.                 res = re.search('(dnssd|mdns)://([^\\./]+)(\\.[^/]+|)/cups', uri)
  3939.                 if res and self.device.id_dict and self.device.id_dict.get('MDL', ''):
  3940.                     resg = res.groups()
  3941.                     self.remotecupsqueue = self.device.info
  3942.                 
  3943.                 if not (self.remotecupsqueue) and not (self.new_printer_PPDs_loaded):
  3944.                     
  3945.                     try:
  3946.                         self.loadPPDs(self.NewPrinterWindow)
  3947.                     except cups.IPPError:
  3948.                         (e, msg) = None
  3949.                         self.ready(self.NewPrinterWindow)
  3950.                         self.show_IPP_Error(e, msg)
  3951.                         return None
  3952.                         self.ready(self.NewPrinterWindow)
  3953.                         return None
  3954.  
  3955.                     self.new_printer_PPDs_loaded = True
  3956.                 
  3957.                 ppdname = None
  3958.                 
  3959.                 try:
  3960.                     if self.remotecupsqueue:
  3961.                         ppdname = 'raw'
  3962.                         self.ppd = ppdname
  3963.                         name = self.remotecupsqueue
  3964.                         name = self.mainapp.makeNameUnique(name)
  3965.                         self.entNPName.set_text(name)
  3966.                     elif (self.device.id or self.device.make_and_model) and self.device.make_and_model != 'Unknown':
  3967.                         if self.device.id:
  3968.                             id_dict = self.device.id_dict
  3969.                         else:
  3970.                             id_dict = { }
  3971.                             (id_dict['MFG'], id_dict['MDL']) = cupshelpers.ppds.ppdMakeModelSplit(self.device.make_and_model)
  3972.                             id_dict['DES'] = ''
  3973.                             id_dict['CMD'] = ()
  3974.                         reloaded = 0
  3975.                         while reloaded < 2:
  3976.                             (status, ppdname) = self.ppds.getPPDNameFromDeviceID(id_dict['MFG'], id_dict['MDL'], id_dict['DES'], id_dict['CMD'], self.device.uri, self.jockey_installed_files)
  3977.                             if status != self.ppds.STATUS_SUCCESS and reloaded == 0:
  3978.                                 
  3979.                                 try:
  3980.                                     if self.fetchJockeyDriver():
  3981.                                         
  3982.                                         try:
  3983.                                             self.dropPPDs()
  3984.                                             self.loadPPDs()
  3985.                                             reloaded = 1
  3986.                                         reloaded = 2
  3987.  
  3988.                                     else:
  3989.                                         reloaded = 2
  3990.                                 reloaded = 2
  3991.  
  3992.                                 continue
  3993.                             reloaded = 2
  3994.                     else:
  3995.                         (status, ppdname) = self.ppds.getPPDNameFromDeviceID('Generic', 'Printer', 'Generic Printer', [], self.device.uri)
  3996.                     if ppdname and not (self.remotecupsqueue):
  3997.                         ppddict = self.ppds.getInfoFromPPDName(ppdname)
  3998.                         make_model = ppddict['ppd-make-and-model']
  3999.                         (make, model) = cupshelpers.ppds.ppdMakeModelSplit(make_model)
  4000.                         self.auto_make = make
  4001.                         self.auto_model = model
  4002.                         if status == self.ppds.STATUS_SUCCESS and self.dialog_mode != 'ppd':
  4003.                             self.exactdrivermatch = True
  4004.                         else:
  4005.                             self.exactdrivermatch = False
  4006.                 except:
  4007.                     nonfatalException()
  4008.  
  4009.                 if not self.remotecupsqueue:
  4010.                     self.fillMakeList()
  4011.                 
  4012.             elif page_nr == 3:
  4013.                 if not self.device.id:
  4014.                     
  4015.                     try:
  4016.                         (model, iter) = self.tvNPModels.get_selection().get_selected()
  4017.                         name = model.get(iter, 0)[0]
  4018.                         name = self.mainapp.makeNameUnique(name)
  4019.                         self.entNPName.set_text(name)
  4020.                     nonfatalException()
  4021.  
  4022.                 
  4023.             
  4024.             self.ready(self.NewPrinterWindow)
  4025.             if self.dialog_mode == 'printer':
  4026.                 if self.remotecupsqueue:
  4027.                     order = [
  4028.                         1,
  4029.                         0]
  4030.                 elif self.exactdrivermatch:
  4031.                     order = [
  4032.                         1,
  4033.                         6,
  4034.                         0]
  4035.                 elif self.rbtnNPFoomatic.get_active():
  4036.                     order = [
  4037.                         1,
  4038.                         2,
  4039.                         3,
  4040.                         6,
  4041.                         0]
  4042.                 elif self.rbtnNPPPD.get_active():
  4043.                     order = [
  4044.                         1,
  4045.                         2,
  4046.                         6,
  4047.                         0]
  4048.                 else:
  4049.                     order = [
  4050.                         1,
  4051.                         2,
  4052.                         7,
  4053.                         6,
  4054.                         0]
  4055.             elif self.remotecupsqueue:
  4056.                 order = [
  4057.                     0]
  4058.             elif self.exactdrivermatch:
  4059.                 order = [
  4060.                     6,
  4061.                     0]
  4062.             elif self.rbtnNPFoomatic.get_active():
  4063.                 order = [
  4064.                     2,
  4065.                     3,
  4066.                     6,
  4067.                     0]
  4068.             elif self.rbtnNPPPD.get_active():
  4069.                 order = [
  4070.                     2,
  4071.                     6,
  4072.                     0]
  4073.             else:
  4074.                 order = [
  4075.                     2,
  4076.                     7,
  4077.                     6,
  4078.                     0]
  4079.         elif self.dialog_mode == 'device':
  4080.             order = [
  4081.                 1]
  4082.         elif self.dialog_mode == 'ppd':
  4083.             if self.rbtnNPFoomatic.get_active():
  4084.                 order = [
  4085.                     2,
  4086.                     3,
  4087.                     5,
  4088.                     6]
  4089.             elif self.rbtnNPPPD.get_active():
  4090.                 order = [
  4091.                     2,
  4092.                     5,
  4093.                     6]
  4094.             else:
  4095.                 order = [
  4096.                     2,
  4097.                     7,
  4098.                     5,
  4099.                     6]
  4100.         
  4101.         next_page_nr = order[order.index(page_nr) + step]
  4102.         fetch_ppd = False
  4103.         
  4104.         try:
  4105.             if order.index(5) > -1:
  4106.                 if next_page_nr == 5:
  4107.                     pass
  4108.                 fetch_ppd = step >= 0
  4109.         except ValueError:
  4110.             if next_page_nr == 6:
  4111.                 pass
  4112.             fetch_ppd = step >= 0
  4113.  
  4114.         debugprint('Will fetch ppd? %d' % fetch_ppd)
  4115.         if fetch_ppd:
  4116.             self.ppd = self.getNPPPD()
  4117.             self.installable_options = False
  4118.             if self.ppd == None:
  4119.                 return None
  4120.             if isinstance(self.ppd, cups.PPD):
  4121.                 self.fillNPInstallableOptions()
  4122.             else:
  4123.                 ppd = self.ppd
  4124.                 self.ppd = None
  4125.                 self.fillNPInstallableOptions()
  4126.                 self.ppd = ppd
  4127.             if not self.installable_options:
  4128.                 if next_page_nr == 6:
  4129.                     next_page_nr = order[order.index(next_page_nr) + 1]
  4130.                 
  4131.             
  4132.         
  4133.         if next_page_nr == 6 and not (self.installable_options) and step < 0:
  4134.             next_page_nr = order[order.index(next_page_nr) - 1]
  4135.         
  4136.         if step >= 0 and next_page_nr == 7:
  4137.             if self.drivers_lock.locked():
  4138.                 self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for drivers'))
  4139.                 self.WaitWindow.set_transient_for(self.NewPrinterWindow)
  4140.                 self.WaitWindow.show()
  4141.                 self.busy(self.WaitWindow)
  4142.                 self.busy(self.NewPrinterWindow)
  4143.                 while self.drivers_lock.locked():
  4144.                     while gtk.events_pending():
  4145.                         gtk.main_iteration()
  4146.                     time.sleep(0.1)
  4147.                 self.ready(self.NewPrinterWindow)
  4148.                 self.WaitWindow.hide()
  4149.             
  4150.             self.fillDownloadableDrivers()
  4151.         
  4152.         if step >= 0 and next_page_nr == 0:
  4153.             name = None
  4154.             descr = None
  4155.             
  4156.             try:
  4157.                 if self.device.id and self.device.type not in ('socket', 'lpd', 'ipp', 'http', 'https', 'bluetooth'):
  4158.                     name = '%s %s' % (self.device.id_dict['MFG'], self.device.id_dict['MDL'])
  4159.                     descr = '%s %s' % (self.device.id_dict['MFG'], self.device.id_dict['MDL'])
  4160.             except:
  4161.                 nonfatalException()
  4162.  
  4163.             
  4164.             try:
  4165.                 if name == None and isinstance(self.ppd, cups.PPD):
  4166.                     mname = self.ppd.findAttr('modelName').value
  4167.                     (make, model) = cupshelpers.ppds.ppdMakeModelSplit(mname)
  4168.                     name = '%s %s' % (make, model)
  4169.                     descr = '%s %s' % (make, model)
  4170.             except:
  4171.                 nonfatalException()
  4172.  
  4173.             if name == None:
  4174.                 name = 'printer'
  4175.             
  4176.             name = self.mainapp.makeNameUnique(name)
  4177.             self.entNPName.set_text(name)
  4178.             if self.entNPDescription.get_text() == '' and descr:
  4179.                 self.entNPDescription.set_text(descr)
  4180.             
  4181.         
  4182.         self.ntbkNewPrinter.set_current_page(next_page_nr)
  4183.         self.setNPButtons()
  4184.  
  4185.     
  4186.     def setNPButtons(self):
  4187.         nr = self.ntbkNewPrinter.get_current_page()
  4188.         if self.dialog_mode == 'device':
  4189.             self.btnNPBack.hide()
  4190.             self.btnNPForward.hide()
  4191.             self.btnNPApply.show()
  4192.             
  4193.             try:
  4194.                 uri = self.getDeviceURI()
  4195.                 valid = validDeviceURI(uri)
  4196.             except AttributeError:
  4197.                 valid = False
  4198.  
  4199.             self.btnNPApply.set_sensitive(valid)
  4200.             return None
  4201.         self.btnNPForward.show()
  4202.         self.btnNPApply.hide()
  4203.         if nr == 2:
  4204.             downloadable_selected = False
  4205.             if self.rbtnNPDownloadableDriverSearch.get_active():
  4206.                 combobox = self.cmbNPDownloadableDriverFoundPrinters
  4207.                 iter = combobox.get_active_iter()
  4208.                 if iter and combobox.get_model().get_value(iter, 1):
  4209.                     downloadable_selected = True
  4210.                 
  4211.             
  4212.             if not self.rbtnNPFoomatic.get_active() and self.filechooserPPD.get_filename():
  4213.                 pass
  4214.             self.btnNPForward.set_sensitive(bool(downloadable_selected))
  4215.             if self.dialog_mode == 'printer_with_uri':
  4216.                 self.btnNPBack.hide()
  4217.             
  4218.         
  4219.         if nr == 3:
  4220.             (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  4221.             self.btnNPForward.set_sensitive(bool(iter))
  4222.         
  4223.         if nr == 4:
  4224.             self.btnNPForward.hide()
  4225.             self.btnNPApply.show()
  4226.             self.btnNPApply.set_sensitive(bool(getCurrentClassMembers(self.tvNCMembers)))
  4227.         
  4228.         if nr == 6:
  4229.             if self.dialog_mode == 'printer_with_uri' and self.exactdrivermatch:
  4230.                 self.btnNPBack.hide()
  4231.             
  4232.         
  4233.         if nr == 7:
  4234.             if self.ntbkNPDownloadableDriverProperties.get_current_page() == 1:
  4235.                 accepted = self.rbtnNPDownloadLicenseYes.get_active()
  4236.             else:
  4237.                 treeview = self.tvNPDownloadableDrivers
  4238.                 (model, iter) = treeview.get_selection().get_selected()
  4239.                 accepted = iter != None
  4240.             self.btnNPForward.set_sensitive(accepted)
  4241.         
  4242.  
  4243.     
  4244.     def on_entNPName_changed(self, widget):
  4245.         text = unicode(widget.get_text())
  4246.         new_text = text
  4247.         new_text = new_text.replace('/', '')
  4248.         new_text = new_text.replace('#', '')
  4249.         new_text = new_text.replace(' ', '')
  4250.         if text != new_text:
  4251.             widget.set_text(new_text)
  4252.         
  4253.         if self.dialog_mode == 'printer':
  4254.             self.btnNPApply.set_sensitive(self.mainapp.checkNPName(new_text))
  4255.         else:
  4256.             self.btnNPForward.set_sensitive(self.mainapp.checkNPName(new_text))
  4257.  
  4258.     
  4259.     def fetchDevices(self, parent = None):
  4260.         debugprint('fetchDevices')
  4261.         self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for printers'))
  4262.         if parent == None:
  4263.             parent = self.mainapp.PrintersWindow
  4264.         
  4265.         self.WaitWindow.set_transient_for(parent)
  4266.         self.WaitWindow.show_now()
  4267.         self.busy(self.WaitWindow)
  4268.         while gtk.events_pending():
  4269.             gtk.main_iteration()
  4270.         debugprint('Fetching devices')
  4271.         self.mainapp.cups._begin_operation(_('fetching device list'))
  4272.         
  4273.         try:
  4274.             devices = cupshelpers.getDevices(self.mainapp.cups)
  4275.         except:
  4276.             self.mainapp.cups._end_operation()
  4277.             self.WaitWindow.hide()
  4278.             raise 
  4279.  
  4280.         self.mainapp.cups._end_operation()
  4281.         self.WaitWindow.hide()
  4282.         debugprint('Got devices')
  4283.         return devices
  4284.  
  4285.     
  4286.     def install_hplip_plugin(self, uri):
  4287.         '''
  4288.         Attempt to install a plugin using hp-plugin.
  4289.  
  4290.         @return: True if plugin not needed (or needed and installed),
  4291.         False on error.
  4292.         '''
  4293.         if not self.HP_PLUGIN_SUPPORT:
  4294.             return True
  4295.         os.environ['URI'] = uri
  4296.         cmd = 'LC_ALL=C DISPLAY= hp-info -x -i -d"${URI}"'
  4297.         debugprint(uri + ': ' + cmd)
  4298.         
  4299.         try:
  4300.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4301.             (stdout, stderr) = p.communicate()
  4302.             if p.returncode != 0:
  4303.                 return True
  4304.         except:
  4305.             self.HP_PLUGIN_SUPPORT
  4306.             return True
  4307.  
  4308.         plugin_needed = -1
  4309.         plugin_reason = -1
  4310.         fw_download = -1
  4311.         hpmodel = None
  4312.         hplip_version = None
  4313.         for line in stdout.split('\n'):
  4314.             if line.find('plugin ') >= 0:
  4315.                 res = re.search('(\\d+)', line)
  4316.                 if res:
  4317.                     resg = res.groups()
  4318.                     plugin_needed = int(resg[0])
  4319.                 
  4320.             elif line.find('plugin-reason') >= 0:
  4321.                 res = re.search('(\\d+)', line)
  4322.                 if res:
  4323.                     resg = res.groups()
  4324.                     plugin_reason = int(resg[0])
  4325.                 
  4326.             elif line.find('fw-download') >= 0:
  4327.                 if line.find('True') >= 0:
  4328.                     fw_download = 1
  4329.                 elif line.find('False') >= 0:
  4330.                     fw_download = 0
  4331.                 
  4332.             elif line.find('model') >= 0:
  4333.                 res = re.search('^\\s*model\\s*(\\S+)\\s*$', line)
  4334.                 if res:
  4335.                     resg = res.groups()
  4336.                     hpmodel = resg[0]
  4337.                 
  4338.             elif line.find('HP Linux Imaging and Printing') >= 0:
  4339.                 res = re.search('(\\d+\\.\\d+\\.\\d+\\w*)', line)
  4340.                 if res:
  4341.                     resg = res.groups()
  4342.                     hplip_version = resg[0]
  4343.                 
  4344.             
  4345.             if plugin_needed >= 0 and plugin_reason >= 0 and fw_download >= 0 and hpmodel != None:
  4346.                 break
  4347.                 continue
  4348.         
  4349.         if plugin_needed <= 0 and not hplip_version or not hpmodel:
  4350.             return True
  4351.         if hplip_version.startswith('3'):
  4352.             os.environ['hp_model'] = hpmodel
  4353.             cmd = 'LC_ALL=C hp-mkuri -c'
  4354.             debugprint(uri + ': ' + hpmodel)
  4355.             
  4356.             try:
  4357.                 p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4358.                 (stdout, stderr) = p.communicate()
  4359.                 if p.returncode < 2:
  4360.                     return True
  4361.             return True
  4362.  
  4363.         elif glob.glob('/usr/share/hplip/data/plugin/*%s*plugin*' % hplip_version):
  4364.             if hplip_version.startswith('2'):
  4365.                 
  4366.                 try:
  4367.                     f = open('/etc/hp/hplip.conf', 'r')
  4368.                     for line in f:
  4369.                         if line.strip().startswith('plugin') and line.strip().endswith('1'):
  4370.                             f.close()
  4371.                             return True
  4372.                         f.close()
  4373.                 except:
  4374.                     not hpmodel
  4375.  
  4376.                 return True
  4377.             hplip_version.startswith('2')
  4378.         
  4379.         text = _('For this printer a proprietary driver plugin from HP is available.\n')
  4380.         if plugin_needed == 1:
  4381.             text += _('The installation of the plugin is required for your printer to work.\n\n')
  4382.         elif plugin_needed == 2:
  4383.             text += _('Installing the plugin is optional, it completes or enhances the functionality\nof your printer. Without plugin at least basic operations work.\n\n')
  4384.         
  4385.         if plugin_reason > 0:
  4386.             text += _('The plugin provides the following features:\n')
  4387.             if plugin_reason & 1 != 0:
  4388.                 text += _(' - Printing support\n')
  4389.             
  4390.             if plugin_reason & 2 != 0:
  4391.                 text += _(' - Faster printing\n')
  4392.             
  4393.             if plugin_reason & 4 != 0:
  4394.                 text += _(' - Better printout quality\n')
  4395.             
  4396.             if plugin_reason & 8 != 0:
  4397.                 text += _(' - Extra printing features\n')
  4398.             
  4399.             if plugin_reason & 64 != 0:
  4400.                 text += _(' - Scanning support\n')
  4401.             
  4402.             if plugin_reason & 128 != 0:
  4403.                 text += _(' - Faster scanning\n')
  4404.             
  4405.             if plugin_reason & 256 != 0:
  4406.                 text += _(' - Better scanning image quality\n')
  4407.             
  4408.             if plugin_reason & 2048 != 0:
  4409.                 text += _(' - Faxing support\n')
  4410.             
  4411.             if plugin_reason & 4096 != 0:
  4412.                 text += _(' - Extra fax features\n')
  4413.             
  4414.             if plugin_reason & 16384 != 0:
  4415.                 text += _(' - Better Input/Output support\n')
  4416.             
  4417.             if plugin_reason & 32768 != 0:
  4418.                 text += _(' - Extra user interface features\n')
  4419.             
  4420.             if plugin_reason & 65536 != 0:
  4421.                 text += _(' - Other extra features\n')
  4422.             
  4423.             text += '\n'
  4424.         
  4425.         text += 'Do you want to download and install the plugin now?\n'
  4426.         if plugin_needed == 1:
  4427.             text += '\nNOTE: The plugin is required for your printer. If you do not install it, your\nprinter will not work.'
  4428.             buttons = (_('Install plugin'), 1, _('Do not set up printer'), 2, _('Set up without plugin'), 3)
  4429.         else:
  4430.             buttons = (_('Yes'), 1, _('No'), 3)
  4431.         dialog = gtk.Dialog(self.device.info, self.NewPrinterWindow, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, buttons)
  4432.         label = gtk.Label(text)
  4433.         dialog.vbox.pack_start(label, True, True, 0)
  4434.         label.show()
  4435.         button_clicked = dialog.run()
  4436.         dialog.destroy()
  4437.         if button_clicked == 1:
  4438.             cmds = ("if python -c 'import PyQt4.QtGui' 2>/dev/null; then gksu -- hp-plugin -u; else exit 255; fi", "gksu -- xterm -T 'HPLIP Plugin Installation' -sb -rightbar -e hp-plugin -i")
  4439.             
  4440.             try:
  4441.                 install_result = -1
  4442.                 for cmd in cmds:
  4443.                     p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4444.                     (stdout, stderr) = p.communicate()
  4445.                     install_result = p.returncode
  4446.                     if install_result != 255:
  4447.                         break
  4448.                         continue
  4449.                 
  4450.                 if install_result == 0:
  4451.                     return True
  4452.                 return False
  4453.             except OSError:
  4454.                 e = None
  4455.                 debugprint('Execution of hp-plugin failed: %s' % e)
  4456.                 return False
  4457.             
  4458.  
  4459.         None<EXCEPTION MATCH>OSError
  4460.         if button_clicked == 2:
  4461.             return False
  4462.         if button_clicked == 3:
  4463.             return True
  4464.         return False
  4465.  
  4466.     
  4467.     def get_hpfax_device_id(self, faxuri):
  4468.         os.environ['URI'] = faxuri
  4469.         cmd = 'LC_ALL=C DISPLAY= hp-info -x -i -d"${URI}"'
  4470.         debugprint(faxuri + ': ' + cmd)
  4471.         
  4472.         try:
  4473.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4474.             (stdout, stderr) = p.communicate()
  4475.         except:
  4476.             return None
  4477.  
  4478.         faxtype = -1
  4479.         for line in stdout.split('\n'):
  4480.             if line.find('fax-type') == -1:
  4481.                 continue
  4482.             
  4483.             res = re.search('(\\d+)', line)
  4484.             if res:
  4485.                 resg = res.groups()
  4486.                 faxtype = resg[0]
  4487.             
  4488.             if faxtype >= 0:
  4489.                 break
  4490.                 continue
  4491.         
  4492.         if faxtype <= 0:
  4493.             return None
  4494.         if faxtype == 4:
  4495.             return 'MFG:HP;MDL:Fax 2;DES:HP Fax 2;'
  4496.         return 'MFG:HP;MDL:Fax;DES:HP Fax;'
  4497.  
  4498.     
  4499.     def get_hplip_uri_for_network_printer(self, host, mode):
  4500.         os.environ['HOST'] = host
  4501.         if mode == 'print':
  4502.             mod = '-c'
  4503.         elif mode == 'fax':
  4504.             mod = '-f'
  4505.         else:
  4506.             mod = '-c'
  4507.         cmd = 'hp-makeuri ' + mod + ' "${HOST}"'
  4508.         debugprint(host + ': ' + cmd)
  4509.         uri = None
  4510.         
  4511.         try:
  4512.             p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4513.             (stdout, stderr) = p.communicate()
  4514.             if p.returncode != 0:
  4515.                 return None
  4516.         except:
  4517.             return None
  4518.  
  4519.         uri = stdout.strip()
  4520.         return uri
  4521.  
  4522.     
  4523.     def getNetworkPrinterMakeModel(self, host = None, device = None):
  4524.         '''
  4525.         Try to determine the make and model for the currently selected
  4526.         network printer, and store this in the data structure for the
  4527.         printer.
  4528.         Returns (hostname or None, uri or None).
  4529.         '''
  4530.         uri = None
  4531.         if device == None:
  4532.             device = self.device
  4533.         
  4534.         if host == None:
  4535.             s = device.uri.find('://')
  4536.             if s != -1:
  4537.                 s += 3
  4538.                 e = device.uri[s:].find(':')
  4539.                 if e == -1:
  4540.                     e = device.uri[s:].find('/')
  4541.                 
  4542.                 if e == -1:
  4543.                     e = device.uri[s:].find('?')
  4544.                 
  4545.                 if e == -1:
  4546.                     e = len(device.uri)
  4547.                 
  4548.                 host = device.uri[s:s + e]
  4549.             
  4550.         
  4551.         if host:
  4552.             os.environ['HOST'] = host
  4553.             cmd = '/usr/lib/cups/backend/snmp "${HOST}"'
  4554.             debugprint(host + ': ' + cmd)
  4555.             stdout = None
  4556.             
  4557.             try:
  4558.                 p = subprocess.Popen(cmd, shell = True, stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  4559.                 (stdout, stderr) = p.communicate()
  4560.                 if p.returncode != 0:
  4561.                     stdout = None
  4562.             except:
  4563.                 pass
  4564.  
  4565.             if stdout != None:
  4566.                 uri = re.sub('^\\s*\\S+\\s+', '', stdout)
  4567.                 uri = re.sub('\\s.*$', '', uri)
  4568.                 mm = re.sub('^\\s*\\S+\\s+\\S+\\s+"', '', stdout)
  4569.                 mm = re.sub('"\\s+.*$', '', mm)
  4570.                 if mm and mm != '':
  4571.                     device.make_and_model = mm
  4572.                 
  4573.             
  4574.         
  4575.         make_and_model = None
  4576.         if len(device.make_and_model) > 7:
  4577.             make_and_model = device.make_and_model
  4578.         elif len(device.info) > 7:
  4579.             make_and_model = device.info
  4580.             make_and_model = re.sub('\\s*(\\(|\\d+\\.\\d+\\.\\d+\\.\\d+).*$', '', make_and_model)
  4581.         
  4582.         if make_and_model and not (device.id):
  4583.             mk = None
  4584.             md = None
  4585.             (mk, md) = cupshelpers.ppds.ppdMakeModelSplit(make_and_model)
  4586.             device.id = 'MFG:' + mk + ';MDL:' + md + ';DES:' + mk + ' ' + md + ';'
  4587.             device.id_dict = cupshelpers.parseDeviceID(device.id)
  4588.             device.make_and_model = '%s %s' % (mk, md)
  4589.             device.info = device.make_and_model
  4590.         
  4591.         return (host, uri)
  4592.  
  4593.     
  4594.     def fillDeviceTab(self, current_uri = None):
  4595.         
  4596.         try:
  4597.             devices = self.fetchDevices()
  4598.         except cups.IPPError:
  4599.             (e, msg) = None
  4600.             self.show_IPP_Error(e, msg)
  4601.             devices = { }
  4602.         except:
  4603.             nonfatalException()
  4604.             devices = { }
  4605.  
  4606.         if current_uri:
  4607.             if devices.has_key(current_uri):
  4608.                 current = devices.pop(current_uri)
  4609.                 current.info += _(' (Current)')
  4610.             elif devices.has_key(current_uri.replace(':9100', '')):
  4611.                 current_uri = current_uri.replace(':9100', '')
  4612.                 current = devices.pop(current_uri)
  4613.                 current.info += _(' (Current)')
  4614.             else:
  4615.                 current = cupshelpers.Device(current_uri)
  4616.                 current.info = 'Current device'
  4617.         
  4618.         devices = devices.values()
  4619.         for device in devices:
  4620.             if device.type == 'socket':
  4621.                 device.uri = device.uri.replace(':9100', '')
  4622.                 continue
  4623.         
  4624.         
  4625.         def replace_generic(device):
  4626.             if device.uri == 'hp:/no_device_found':
  4627.                 device.uri = 'hp'
  4628.             elif device.uri == 'hpfax:/no_device_found':
  4629.                 device.uri = 'hpfax'
  4630.             
  4631.             return device
  4632.  
  4633.         devices = map(replace_generic, devices)
  4634.         for i in range(len(devices) - 1):
  4635.             for j in range(i + 1, len(devices)):
  4636.                 device1 = devices[i]
  4637.                 device2 = devices[j]
  4638.                 if device1.uri == 'delete' or device2.uri == 'delete':
  4639.                     continue
  4640.                 
  4641.                 if device1.uri == device2.uri:
  4642.                     if not device1.id:
  4643.                         device1.uri = 'delete'
  4644.                     elif not device2.id:
  4645.                         device2.uri = 'delete'
  4646.                     elif len(device1.id) < len(device2.id):
  4647.                         device1.uri = 'delete'
  4648.                     else:
  4649.                         device2.uri = 'delete'
  4650.                 device1.id
  4651.             
  4652.         
  4653.         devices = filter((lambda x: x.uri not in ('hp', 'hpfax', 'hal', 'beh', 'scsi', 'http', 'delete')), devices)
  4654.         self.devices = []
  4655.         for device in devices:
  4656.             physicaldevice = PhysicalDevice(device)
  4657.             
  4658.             try:
  4659.                 i = self.devices.index(physicaldevice)
  4660.                 self.devices[i].add_device(device)
  4661.             continue
  4662.             except ValueError:
  4663.                 self.devices.append(physicaldevice)
  4664.                 continue
  4665.             
  4666.  
  4667.         
  4668.         self.devices.sort()
  4669.         other = cupshelpers.Device('', **{
  4670.             'device-info': _('Other') })
  4671.         self.devices.append(PhysicalDevice(other))
  4672.         device_select_index = 0
  4673.         if current_uri:
  4674.             current_device = PhysicalDevice(current)
  4675.             
  4676.             try:
  4677.                 i = self.devices.index(current_device)
  4678.                 self.devices[i].add_device(current)
  4679.                 device_select_index = i
  4680.                 devs = self.devices[i].get_devices()
  4681.             except ValueError:
  4682.                 None<EXCEPTION MATCH>ValueError
  4683.                 None<EXCEPTION MATCH>ValueError
  4684.                 self.devices.insert(0, current_device)
  4685.             except:
  4686.                 None<EXCEPTION MATCH>ValueError<EXCEPTION MATCH>ValueError
  4687.             
  4688.  
  4689.         None<EXCEPTION MATCH>ValueError
  4690.         model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN)
  4691.         network_iter = model.append(None, row = [
  4692.             _('Network Printer'),
  4693.             None,
  4694.             False])
  4695.         network_dict = {
  4696.             'device-class': 'network',
  4697.             'device-info': _('Find Network Printer') }
  4698.         network = cupshelpers.Device('network', **network_dict)
  4699.         find_nw_iter = model.append(network_iter, row = [
  4700.             network_dict['device-info'],
  4701.             PhysicalDevice(network),
  4702.             False])
  4703.         model.insert_after(network_iter, find_nw_iter, row = [
  4704.             '',
  4705.             None,
  4706.             True])
  4707.         self.devices_find_nw_iter = find_nw_iter
  4708.         self.tvNPDevices.set_model(model)
  4709.         i = 0
  4710.         device_select_path = None
  4711.         for device in self.devices:
  4712.             devs = device.get_devices()
  4713.             network = devs[0].device_class == 'network'
  4714.             row = [
  4715.                 device.get_info(),
  4716.                 device,
  4717.                 False]
  4718.             if network:
  4719.                 if devs[0].uri != devs[0].type:
  4720.                     iter = model.insert_before(network_iter, find_nw_iter, row = row)
  4721.                     if device_select_index == i:
  4722.                         network_path = model.get_path(network_iter)
  4723.                         self.tvNPDevices.expand_row(network_path, False)
  4724.                     
  4725.                 else:
  4726.                     iter = model.append(network_iter, row = row)
  4727.             else:
  4728.                 iter = model.insert_before(None, network_iter, row = row)
  4729.             if device_select_index == i:
  4730.                 device_select_path = model.get_path(iter)
  4731.                 self.tvNPDevices.scroll_to_cell(device_select_path, row_align = 0.5)
  4732.                 column = self.tvNPDevices.get_column(0)
  4733.                 self.tvNPDevices.set_cursor(device_select_path, column)
  4734.             
  4735.             i += 1
  4736.         
  4737.         connection_select_path = 0
  4738.         if current_uri:
  4739.             model = self.tvNPDeviceURIs.get_model()
  4740.             iter = model.get_iter_first()
  4741.             i = 0
  4742.             while iter:
  4743.                 dev = model.get_value(iter, 1)
  4744.                 if current_uri == dev.uri:
  4745.                     connection_select_path = i
  4746.                     break
  4747.                 
  4748.                 iter = model.iter_next(iter)
  4749.                 i += 1
  4750.         
  4751.         column = self.tvNPDeviceURIs.get_column(0)
  4752.         self.tvNPDeviceURIs.set_cursor(connection_select_path, column)
  4753.  
  4754.     
  4755.     def on_entNPTDevice_changed(self, entry):
  4756.         self.setNPButtons()
  4757.  
  4758.     
  4759.     def browse_smb_hosts(self):
  4760.         '''Initialise the SMB tree store.'''
  4761.         store = self.smb_store
  4762.         store.clear()
  4763.         self.busy(self.SMBBrowseDialog)
  4764.         
  4765.         class X:
  4766.             pass
  4767.  
  4768.         dummy = X()
  4769.         dummy.smbc_type = pysmb.smbc.PRINTER_SHARE
  4770.         dummy.name = _('Scanning...')
  4771.         dummy.comment = ''
  4772.         store.append(None, [
  4773.             dummy])
  4774.         while gtk.events_pending():
  4775.             gtk.main_iteration()
  4776.         debug = 0
  4777.         if get_debugging():
  4778.             debug = 10
  4779.         
  4780.         smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4781.         ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4782.         entries = None
  4783.         
  4784.         try:
  4785.             while smbc_auth.perform_authentication() > 0:
  4786.                 
  4787.                 try:
  4788.                     entries = ctx.opendir('smb://').getdents()
  4789.                 continue
  4790.                 except Exception:
  4791.                     e = None
  4792.                     smbc_auth.failed(e)
  4793.                     continue
  4794.                 
  4795.  
  4796.                 None<EXCEPTION MATCH>Exception
  4797.         except RuntimeError:
  4798.             (e, s) = None
  4799.             if e != errno.ENOENT:
  4800.                 debugprint('Runtime error: %s' % repr((e, s)))
  4801.             
  4802.         except:
  4803.             e != errno.ENOENT
  4804.             nonfatalException()
  4805.  
  4806.         store.clear()
  4807.         if entries:
  4808.             for entry in entries:
  4809.                 if entry.smbc_type in [
  4810.                     pysmb.smbc.WORKGROUP,
  4811.                     pysmb.smbc.SERVER]:
  4812.                     iter = store.append(None, [
  4813.                         entry])
  4814.                     i = store.append(iter)
  4815.                     continue
  4816.             
  4817.         
  4818.         specified_uri = SMBURI(uri = self.entSMBURI.get_text())
  4819.         (group, host, share, user, password) = specified_uri.separate()
  4820.         if len(host) > 0:
  4821.             
  4822.             class FakeEntry:
  4823.                 pass
  4824.  
  4825.             toplevel = FakeEntry()
  4826.             toplevel.smbc_type = pysmb.smbc.SERVER
  4827.             toplevel.name = host
  4828.             toplevel.comment = ''
  4829.             iter = store.append(None, [
  4830.                 toplevel])
  4831.             i = store.append(iter)
  4832.             path = store.get_path(iter)
  4833.             self.tvSMBBrowser.expand_row(path, 0)
  4834.         
  4835.         self.ready(self.SMBBrowseDialog)
  4836.         if store.get_iter_first() == None:
  4837.             self.SMBBrowseDialog.hide()
  4838.             show_info_dialog(_('No Print Shares'), _('There were no print shares found.  Please check that the Samba service is marked as trusted in your firewall configuration.') + '\n\n' + TEXT_start_firewall_tool, parent = self.NewPrinterWindow)
  4839.         
  4840.  
  4841.     
  4842.     def smb_select_function(self, path):
  4843.         """Don't allow this path to be selected unless it is a leaf."""
  4844.         iter = self.smb_store.get_iter(path)
  4845.         return not self.smb_store.iter_has_child(iter)
  4846.  
  4847.     
  4848.     def smbbrowser_cell_share(self, column, cell, model, iter):
  4849.         entry = model.get_value(iter, 0)
  4850.         share = ''
  4851.         if entry != None:
  4852.             share = entry.name
  4853.         
  4854.         cell.set_property('text', share)
  4855.  
  4856.     
  4857.     def smbbrowser_cell_comment(self, column, cell, model, iter):
  4858.         entry = model.get_value(iter, 0)
  4859.         comment = ''
  4860.         if entry != None:
  4861.             comment = entry.comment
  4862.         
  4863.         cell.set_property('text', comment)
  4864.  
  4865.     
  4866.     def on_tvSMBBrowser_row_activated(self, view, path, column):
  4867.         '''Handle double-clicks in the SMB tree view.'''
  4868.         store = self.smb_store
  4869.         iter = store.get_iter(path)
  4870.         entry = store.get_value(iter, 0)
  4871.         if entry and entry.smbc_type == pysmb.smbc.PRINTER_SHARE:
  4872.             self.btnSMBBrowseOk.clicked()
  4873.             return None
  4874.         if view.row_expanded(path):
  4875.             view.collapse_row(path)
  4876.         else:
  4877.             self.on_tvSMBBrowser_row_expanded(view, iter, path)
  4878.  
  4879.     
  4880.     def on_tvSMBBrowser_row_expanded(self, view, iter, path):
  4881.         '''Handler for expanding a row in the SMB tree view.'''
  4882.         model = view.get_model()
  4883.         entry = model.get_value(iter, 0)
  4884.         if entry == None:
  4885.             return None
  4886.         if entry.smbc_type == pysmb.smbc.WORKGROUP:
  4887.             
  4888.             try:
  4889.                 if self.expanding_row:
  4890.                     return None
  4891.             except:
  4892.                 entry == None
  4893.                 self.expanding_row = 1
  4894.  
  4895.             self.busy(self.SMBBrowseDialog)
  4896.             uri = 'smb://%s/' % entry.name
  4897.             debug = 0
  4898.             if get_debugging():
  4899.                 debug = 10
  4900.             
  4901.             smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4902.             ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4903.             entries = []
  4904.             
  4905.             try:
  4906.                 while smbc_auth.perform_authentication() > 0:
  4907.                     
  4908.                     try:
  4909.                         entries = ctx.opendir(uri).getdents()
  4910.                     continue
  4911.                     except Exception:
  4912.                         e = None
  4913.                         smbc_auth.failed(e)
  4914.                         continue
  4915.                     
  4916.  
  4917.                     None<EXCEPTION MATCH>Exception
  4918.             except RuntimeError:
  4919.                 (e, s) = None
  4920.                 if e != errno.ENOENT:
  4921.                     debugprint('Runtime error: %s' % repr((e, s)))
  4922.                 
  4923.             except:
  4924.                 e != errno.ENOENT
  4925.                 nonfatalException()
  4926.  
  4927.             while model.iter_has_child(iter):
  4928.                 i = model.iter_nth_child(iter, 0)
  4929.                 model.remove(i)
  4930.             for entry in entries:
  4931.                 if entry.smbc_type in [
  4932.                     pysmb.smbc.SERVER,
  4933.                     pysmb.smbc.PRINTER_SHARE]:
  4934.                     i = model.append(iter, [
  4935.                         entry])
  4936.                 
  4937.                 if entry.smbc_type == pysmb.smbc.SERVER:
  4938.                     n = model.append(i)
  4939.                     continue
  4940.             
  4941.             view.expand_row(path, 0)
  4942.             del self.expanding_row
  4943.             self.ready(self.SMBBrowseDialog)
  4944.         elif entry.smbc_type == pysmb.smbc.SERVER:
  4945.             
  4946.             try:
  4947.                 if self.expanding_row:
  4948.                     return None
  4949.             except:
  4950.                 entry == None
  4951.                 self.expanding_row = 1
  4952.  
  4953.             self.busy(self.SMBBrowseDialog)
  4954.             uri = 'smb://%s/' % entry.name
  4955.             debug = 0
  4956.             if get_debugging():
  4957.                 debug = 10
  4958.             
  4959.             smbc_auth = pysmb.AuthContext(self.SMBBrowseDialog)
  4960.             ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  4961.             shares = []
  4962.             
  4963.             try:
  4964.                 while smbc_auth.perform_authentication() > 0:
  4965.                     
  4966.                     try:
  4967.                         shares = ctx.opendir(uri).getdents()
  4968.                     continue
  4969.                     except Exception:
  4970.                         e = None
  4971.                         smbc_auth.failed(e)
  4972.                         continue
  4973.                     
  4974.  
  4975.                     None<EXCEPTION MATCH>Exception
  4976.             except RuntimeError:
  4977.                 (e, s) = None
  4978.                 if e != errno.EACCES and e != errno.EPERM:
  4979.                     debugprint('Runtime error: %s' % repr((e, s)))
  4980.                 
  4981.             except:
  4982.                 e != errno.EPERM
  4983.                 nonfatalException()
  4984.  
  4985.             while model.iter_has_child(iter):
  4986.                 i = model.iter_nth_child(iter, 0)
  4987.                 model.remove(i)
  4988.             for share in shares:
  4989.                 if share.smbc_type == pysmb.smbc.PRINTER_SHARE:
  4990.                     i = model.append(iter, [
  4991.                         share])
  4992.                     debugprint(repr(share))
  4993.                     continue
  4994.             
  4995.             view.expand_row(path, 0)
  4996.             del self.expanding_row
  4997.             self.ready(self.SMBBrowseDialog)
  4998.         
  4999.  
  5000.     
  5001.     def on_entSMBURI_changed(self, ent):
  5002.         uri = ent.get_text()
  5003.         (group, host, share, user, password) = SMBURI(uri = uri).separate()
  5004.         if user:
  5005.             self.entSMBUsername.set_text(user)
  5006.         
  5007.         if password:
  5008.             self.entSMBPassword.set_text(password)
  5009.         
  5010.         if user or password:
  5011.             uri = SMBURI(group = group, host = host, share = share).get_uri()
  5012.             ent.set_text(uri)
  5013.             self.rbtnSMBAuthSet.set_active(True)
  5014.         elif self.entSMBUsername.get_text() == '':
  5015.             self.rbtnSMBAuthPrompt.set_active(True)
  5016.         
  5017.         self.btnSMBVerify.set_sensitive(bool(uri))
  5018.         self.setNPButtons()
  5019.  
  5020.     
  5021.     def on_tvSMBBrowser_cursor_changed(self, widget):
  5022.         (store, iter) = self.tvSMBBrowser.get_selection().get_selected()
  5023.         is_share = False
  5024.         if iter:
  5025.             entry = store.get_value(iter, 0)
  5026.             if entry:
  5027.                 is_share = entry.smbc_type == pysmb.smbc.PRINTER_SHARE
  5028.             
  5029.         
  5030.         if iter != None:
  5031.             pass
  5032.         self.btnSMBBrowseOk.set_sensitive(is_share)
  5033.  
  5034.     
  5035.     def on_btnSMBBrowse_clicked(self, button):
  5036.         self.btnSMBBrowseOk.set_sensitive(False)
  5037.         self.SMBBrowseDialog.show()
  5038.         self.browse_smb_hosts()
  5039.  
  5040.     
  5041.     def on_btnSMBBrowseOk_clicked(self, button):
  5042.         (store, iter) = self.tvSMBBrowser.get_selection().get_selected()
  5043.         is_share = False
  5044.         if iter:
  5045.             entry = store.get_value(iter, 0)
  5046.             if entry:
  5047.                 is_share = entry.smbc_type == pysmb.smbc.PRINTER_SHARE
  5048.             
  5049.         
  5050.         if not iter or not is_share:
  5051.             self.SMBBrowseDialog.hide()
  5052.             return None
  5053.         parent_iter = store.iter_parent(iter)
  5054.         domain_iter = store.iter_parent(parent_iter)
  5055.         share = store.get_value(iter, 0)
  5056.         host = store.get_value(parent_iter, 0)
  5057.         if domain_iter:
  5058.             group = store.get_value(domain_iter, 0).name
  5059.         else:
  5060.             group = ''
  5061.         uri = SMBURI(group = group, host = host.name, share = share.name).get_uri()
  5062.         self.entSMBUsername.set_text('')
  5063.         self.entSMBPassword.set_text('')
  5064.         self.entSMBURI.set_text(uri)
  5065.         self.SMBBrowseDialog.hide()
  5066.  
  5067.     
  5068.     def on_btnSMBBrowseCancel_clicked(self, widget, *args):
  5069.         self.SMBBrowseDialog.hide()
  5070.  
  5071.     
  5072.     def on_btnSMBBrowseRefresh_clicked(self, button):
  5073.         self.browse_smb_hosts()
  5074.  
  5075.     
  5076.     def on_rbtnSMBAuthSet_toggled(self, widget):
  5077.         self.tblSMBAuth.set_sensitive(widget.get_active())
  5078.  
  5079.     
  5080.     def on_btnSMBVerify_clicked(self, button):
  5081.         uri = self.entSMBURI.get_text()
  5082.         (group, host, share, u, p) = SMBURI(uri = uri).separate()
  5083.         user = ''
  5084.         passwd = ''
  5085.         reason = None
  5086.         auth_set = self.rbtnSMBAuthSet.get_active()
  5087.         if auth_set:
  5088.             user = self.entSMBUsername.get_text()
  5089.             passwd = self.entSMBPassword.get_text()
  5090.         
  5091.         accessible = False
  5092.         canceled = False
  5093.         self.busy()
  5094.         
  5095.         try:
  5096.             debug = 0
  5097.             if get_debugging():
  5098.                 debug = 10
  5099.             
  5100.             if auth_set:
  5101.                 
  5102.                 def do_auth(svr, shr, wg, un, pw):
  5103.                     return (group, user, passwd)
  5104.  
  5105.                 ctx = pysmb.smbc.Context(debug = debug, auth_fn = do_auth)
  5106.                 f = ctx.open('smb://%s/%s' % (host, share), os.O_RDWR, 511)
  5107.                 accessible = True
  5108.             else:
  5109.                 smbc_auth = pysmb.AuthContext(self.NewPrinterWindow, workgroup = group, user = user, passwd = passwd)
  5110.                 ctx = pysmb.smbc.Context(debug = debug, auth_fn = smbc_auth.callback)
  5111.                 while smbc_auth.perform_authentication() > 0:
  5112.                     
  5113.                     try:
  5114.                         f = ctx.open('smb://%s/%s' % (host, share), os.O_RDWR, 511)
  5115.                         accessible = True
  5116.                     continue
  5117.                     except Exception:
  5118.                         e = None
  5119.                         smbc_auth.failed(e)
  5120.                         continue
  5121.                     
  5122.  
  5123.                     None<EXCEPTION MATCH>Exception
  5124.                 if not accessible:
  5125.                     canceled = True
  5126.         except RuntimeError:
  5127.             (e, s) = None
  5128.             debugprint('Error accessing share: %s' % repr((e, s)))
  5129.             reason = s
  5130.         except:
  5131.             nonfatalException()
  5132.         
  5133.  
  5134.         self.ready()
  5135.         if accessible:
  5136.             show_info_dialog(_('Print Share Verified'), _('This print share is accessible.'), parent = self.NewPrinterWindow)
  5137.             return None
  5138.  
  5139.     
  5140.     def update_IPP_URI_label(self):
  5141.         hostname = self.entNPTIPPHostname.get_text()
  5142.         queue = self.entNPTIPPQueuename.get_text()
  5143.         if len(hostname) > 0:
  5144.             pass
  5145.         valid = queue != '/printers/'
  5146.         if valid:
  5147.             uri = '%s://%s%s' % (self.device.type, hostname, queue)
  5148.             self.lblIPPURI.set_text(uri)
  5149.             self.lblIPPURI.show()
  5150.             self.entNPTIPPQueuename.show()
  5151.         else:
  5152.             self.lblIPPURI.hide()
  5153.         self.btnIPPVerify.set_sensitive(valid)
  5154.         self.setNPButtons()
  5155.  
  5156.     
  5157.     def on_entNPTIPPHostname_changed(self, ent):
  5158.         valid = len(ent.get_text()) > 0
  5159.         self.update_IPP_URI_label()
  5160.  
  5161.     
  5162.     def on_entNPTIPPQueuename_changed(self, ent):
  5163.         self.update_IPP_URI_label()
  5164.  
  5165.     
  5166.     def on_btnIPPVerify_clicked(self, button):
  5167.         uri = self.lblIPPURI.get_text()
  5168.         (scheme, rest) = urllib.splittype(uri)
  5169.         (hostport, rest) = urllib.splithost(rest)
  5170.         verified = False
  5171.         if hostport != None:
  5172.             (host, port) = urllib.splitnport(hostport, defport = 631)
  5173.             if uri.startswith('https:'):
  5174.                 encryption = cups.HTTP_ENCRYPT_ALWAYS
  5175.             else:
  5176.                 encryption = cups.HTTP_ENCRYPT_IF_REQUESTED
  5177.             
  5178.             def get_attributes():
  5179.                 c = cups.Connection(host = host, port = port, encryption = encryption)
  5180.                 return c.getPrinterAttributes(uri = uri)
  5181.  
  5182.             op = TimedOperation(get_attributes)
  5183.             self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Verifying') + '</span>\n\n' + _('Verifying printer'))
  5184.             self.WaitWindow.set_transient_for(self.NewPrinterWindow)
  5185.             self.WaitWindow.show()
  5186.             self.busy(self.WaitWindow)
  5187.             source = gobject.timeout_add(10000, op.cancel)
  5188.             
  5189.             try:
  5190.                 attributes = op.run()
  5191.                 verified = True
  5192.             except OperationCanceled:
  5193.                 (None, None, None, None)
  5194.                 (None, None, None, None)
  5195.             except cups.IPPError:
  5196.                 (e, msg) = None
  5197.                 debugprint('Failed to get attributes: %s (%d)' % (msg, e))
  5198.             except:
  5199.                 (None, None, None, None)
  5200.                 nonfatalException()
  5201.  
  5202.             gobject.source_remove(source)
  5203.             self.WaitWindow.hide()
  5204.         else:
  5205.             debugprint(uri)
  5206.         if verified:
  5207.             show_info_dialog(_('Print Share Verified'), _('This print share is accessible.'), parent = self.NewPrinterWindow)
  5208.         else:
  5209.             show_error_dialog(_('Inaccessible'), _('This print share is not accessible.'), self.NewPrinterWindow)
  5210.  
  5211.     
  5212.     def on_expNPDeviceURIs_expanded(self, widget, UNUSED):
  5213.         parent = widget.get_parent()
  5214.         (expand, fill, padding, pack_type) = parent.query_child_packing(widget)
  5215.         expand = widget.get_expanded()
  5216.         parent.set_child_packing(widget, expand, fill, padding, pack_type)
  5217.  
  5218.     
  5219.     def device_row_separator_fn(self, model, iter):
  5220.         return model.get_value(iter, 2)
  5221.  
  5222.     
  5223.     def device_row_activated(self, view, path, column):
  5224.         if view.row_expanded(path):
  5225.             view.collapse_row(path)
  5226.         else:
  5227.             view.expand_row(path, False)
  5228.  
  5229.     
  5230.     def device_select_function(self, path):
  5231.         '''
  5232.         Allow this path to be selected as long as there
  5233.         is a device associated with it.  Otherwise, expand or collapse it.
  5234.         '''
  5235.         model = self.tvNPDevices.get_model()
  5236.         iter = model.get_iter(path)
  5237.         if model.get_value(iter, 1) != None:
  5238.             return True
  5239.         self.device_row_activated(self.tvNPDevices, path, None)
  5240.         return False
  5241.  
  5242.     
  5243.     def on_tvNPDevices_cursor_changed(self, widget):
  5244.         (path, column) = widget.get_cursor()
  5245.         if path == None:
  5246.             return None
  5247.         model = widget.get_model()
  5248.         iter = model.get_iter(path)
  5249.         physicaldevice = model.get_value(iter, 1)
  5250.         if physicaldevice == None:
  5251.             return None
  5252.         for device in physicaldevice.get_devices():
  5253.             if device.type == 'parallel':
  5254.                 device.menuentry = _('Parallel Port')
  5255.                 continue
  5256.             physicaldevice == None
  5257.             if device.type == 'serial':
  5258.                 device.menuentry = _('Serial Port')
  5259.                 continue
  5260.             path == None
  5261.             if device.type == 'usb':
  5262.                 device.menuentry = _('USB')
  5263.                 continue
  5264.             if device.type == 'bluetooth':
  5265.                 device.menuentry = _('Bluetooth')
  5266.                 continue
  5267.             if device.type == 'hp':
  5268.                 device.menuentry = _('HP Linux Imaging and Printing (HPLIP)')
  5269.                 continue
  5270.             if device.type == 'hpfax':
  5271.                 device.menuentry = _('Fax') + ' - ' + _('HP Linux Imaging and Printing (HPLIP)')
  5272.                 continue
  5273.             if device.type == 'hal':
  5274.                 device.menuentry = _('Hardware Abstraction Layer (HAL)')
  5275.                 continue
  5276.             if device.type == 'socket':
  5277.                 device.menuentry = _('AppSocket/HP JetDirect')
  5278.                 continue
  5279.             if device.type == 'lpd':
  5280.                 (scheme, rest) = urllib.splittype(device.uri)
  5281.                 (hostport, rest) = urllib.splithost(rest)
  5282.                 (queue, rest) = urllib.splitquery(rest)
  5283.                 if queue[0] == '/':
  5284.                     queue = queue[1:]
  5285.                 
  5286.                 if queue != '':
  5287.                     device.menuentry = _("LPD/LPR queue '%s'") % queue
  5288.                 else:
  5289.                     device.menuentry = _('LPD/LPR queue')
  5290.             queue != ''
  5291.             if device.type == 'smb':
  5292.                 device.menuentry = _('Windows Printer via SAMBA')
  5293.                 continue
  5294.             if device.type == 'ipp':
  5295.                 device.menuentry = _('IPP')
  5296.                 continue
  5297.             if device.type == 'http' or device.type == 'https':
  5298.                 device.menuentry = _('HTTP')
  5299.                 continue
  5300.             if device.type == 'dnssd' or device.type == 'mdns':
  5301.                 (scheme, rest) = urllib.splittype(device.uri)
  5302.                 (name, rest) = urllib.splithost(rest)
  5303.                 (cupsqueue, rest) = urllib.splitquery(rest)
  5304.                 if cupsqueue[0] == '/':
  5305.                     cupsqueue = cupsqueue[1:]
  5306.                 
  5307.             None if cupsqueue == 'cups' else protocol != None
  5308.             device.menuentry = device.uri
  5309.         
  5310.         model = gtk.ListStore(str, gobject.TYPE_PYOBJECT)
  5311.         self.tvNPDeviceURIs.set_model(model)
  5312.         if physicaldevice.get_data('checked-hplip') != True:
  5313.             hp_drivable = False
  5314.             is_network = False
  5315.             remotecups = False
  5316.             host = None
  5317.             device_dict = {
  5318.                 'device-class': 'network' }
  5319.             if physicaldevice._network_host:
  5320.                 host = physicaldevice._network_host
  5321.             
  5322.             for device in physicaldevice.get_devices():
  5323.                 if device.type == 'hp':
  5324.                     hp_drivable = True
  5325.                     break
  5326.                     continue
  5327.                 if device.type in ('socket', 'lpd', 'ipp', 'dnssd', 'mdns'):
  5328.                     if host == None and device.type in ('socket', 'lpd', 'ipp'):
  5329.                         (scheme, rest) = urllib.splittype(device.uri)
  5330.                         (hostport, rest) = urllib.splithost(rest)
  5331.                         if hostport != None:
  5332.                             (host, port) = urllib.splitport(hostport)
  5333.                         
  5334.                     
  5335.                     if host:
  5336.                         is_network = True
  5337.                         if device.uri.startswith('dnssd:') or device.uri.startswith('mdns:'):
  5338.                             pass
  5339.                         remotecups = device.uri.endswith('/cups')
  5340.                         if (not (device.make_and_model) or device.make_and_model == 'Unknown') and not remotecups:
  5341.                             self.getNetworkPrinterMakeModel(host = host, device = device)
  5342.                         
  5343.                         device_dict['device-info'] = device.info
  5344.                         device_dict['device-make-and-model'] = device.make_and_model
  5345.                         device_dict['device-id'] = device.id
  5346.                     
  5347.                 host
  5348.             
  5349.             if not hp_drivable and is_network and not remotecups:
  5350.                 hplipuri = self.get_hplip_uri_for_network_printer(host, 'print')
  5351.                 if hplipuri:
  5352.                     dev = cupshelpers.Device(hplipuri, **device_dict)
  5353.                     dev.menuentry = 'HP Linux Imaging and Printing (HPLIP)'
  5354.                     physicaldevice.add_device(dev)
  5355.                     faxuri = self.get_hplip_uri_for_network_printer(host, 'fax')
  5356.                     if faxuri:
  5357.                         faxdevid = self.get_hpfax_device_id(faxuri)
  5358.                         device_dict['device-id'] = faxdevid
  5359.                         device_dict['device-info'] = _('Fax')
  5360.                         faxdev = cupshelpers.Device(faxuri, **device_dict)
  5361.                         faxdev.menuentry = _('Fax') + ' - ' + 'HP Linux Imaging and Printing (HPLIP)'
  5362.                         physicaldevice.add_device(faxdev)
  5363.                     
  5364.                 
  5365.                 physicaldevice.set_data('checked-hplip', True)
  5366.             
  5367.         
  5368.         n = 0
  5369.         for device in physicaldevice.get_devices():
  5370.             model.append((device.menuentry, device))
  5371.             n += 1
  5372.         
  5373.         column = self.tvNPDeviceURIs.get_column(0)
  5374.         self.tvNPDeviceURIs.set_cursor(0, column)
  5375.         if n > 1:
  5376.             self.expNPDeviceURIs.show_all()
  5377.         else:
  5378.             self.expNPDeviceURIs.hide()
  5379.  
  5380.     
  5381.     def on_tvNPDeviceURIs_cursor_changed(self, widget):
  5382.         (path, column) = widget.get_cursor()
  5383.         if path == None:
  5384.             return None
  5385.         model = widget.get_model()
  5386.         iter = model.get_iter(path)
  5387.         device = model.get_value(iter, 1)
  5388.         self.device = device
  5389.         self.lblNPDeviceDescription.set_text('')
  5390.         page = self.new_printer_device_tabs.get(device.type, 1)
  5391.         self.ntbkNPType.set_current_page(page)
  5392.         location = ''
  5393.         type = device.type
  5394.         url = device.uri.split(':', 1)[-1]
  5395.         if page == 0:
  5396.             if device.type == 'parallel':
  5397.                 text = _('A printer connected to the parallel port.')
  5398.             elif device.type == 'usb':
  5399.                 text = _('A printer connected to a USB port.')
  5400.             elif device.type == 'bluetooth':
  5401.                 text = _('A printer connected via Bluetooth.')
  5402.             elif device.type == 'hp':
  5403.                 text = _('HPLIP software driving a printer, or the printer function of a multi-function device.')
  5404.             elif device.type == 'hpfax':
  5405.                 text = _('HPLIP software driving a fax machine, or the fax function of a multi-function device.')
  5406.             elif device.type == 'hal':
  5407.                 text = _('Local printer detected by the Hardware Abstraction Layer (HAL).')
  5408.             elif device.type == 'dnssd' or device.type == 'mdns':
  5409.                 (scheme, rest) = urllib.splittype(device.uri)
  5410.                 (name, rest) = urllib.splithost(rest)
  5411.                 (cupsqueue, rest) = urllib.splitquery(rest)
  5412.                 if cupsqueue[0] == '/':
  5413.                     cupsqueue = cupsqueue[1:]
  5414.                 
  5415.                 if cupsqueue == 'cups':
  5416.                     text = _('Remote CUPS printer via DNS-SD')
  5417.                 else:
  5418.                     protocol = None
  5419.                     if name.find('._ipp') != -1:
  5420.                         protocol = 'IPP'
  5421.                     elif name.find('._printer') != -1:
  5422.                         protocol = 'LPD'
  5423.                     elif name.find('._pdl-datastream') != -1:
  5424.                         protocol = 'AppSocket/JetDirect'
  5425.                     
  5426.                     if protocol != None:
  5427.                         text = _('%s network printer via DNS-SD') % protocol
  5428.                     else:
  5429.                         text = _('Network printer via DNS-SD')
  5430.             else:
  5431.                 text = device.uri
  5432.             self.lblNPDeviceDescription.set_text(text)
  5433.         elif device.type == 'socket':
  5434.             (scheme, rest) = urllib.splittype(device.uri)
  5435.             host = ''
  5436.             port = 9100
  5437.             if scheme == 'socket':
  5438.                 (hostport, rest) = urllib.splithost(rest)
  5439.                 (host, port) = urllib.splitnport(hostport, defport = port)
  5440.                 debugprint('socket: host is %s, port is %s' % (host, repr(port)))
  5441.                 location = host
  5442.             
  5443.             self.entNPTDirectJetHostname.set_text(host)
  5444.             self.entNPTDirectJetPort.set_text(str(port))
  5445.         elif device.type == 'serial':
  5446.             if not device.is_class:
  5447.                 options = device.uri.split('?')[1]
  5448.                 options = options.split('+')
  5449.                 option_dict = { }
  5450.                 for option in options:
  5451.                     (name, value) = option.split('=')
  5452.                     option_dict[name] = value
  5453.                 
  5454.                 for widget, name, optionvalues in ((self.cmbNPTSerialBaud, 'baud', None), (self.cmbNPTSerialBits, 'bits', None), (self.cmbNPTSerialParity, 'parity', [
  5455.                     'none',
  5456.                     'odd',
  5457.                     'even']), (self.cmbNPTSerialFlow, 'flow', [
  5458.                     'none',
  5459.                     'soft',
  5460.                     'hard',
  5461.                     'hard'])):
  5462.                     if option_dict.has_key(name):
  5463.                         if optionvalues is None:
  5464.                             model = widget.get_model()
  5465.                             iter = model.get_iter_first()
  5466.                             nr = 0
  5467.                             while iter:
  5468.                                 value = model.get(iter, 0)[0]
  5469.                                 if value == option_dict[name]:
  5470.                                     widget.set_active(nr)
  5471.                                     break
  5472.                                 
  5473.                                 iter = model.iter_next(iter)
  5474.                                 nr += 1
  5475.                         else:
  5476.                             nr = optionvalues.index(option_dict[name])
  5477.                             widget.set_active(nr + 1)
  5478.                     optionvalues is None
  5479.                     widget.set_active(0)
  5480.                 
  5481.             
  5482.         elif device.type in ('ipp', 'http', 'https'):
  5483.             if device.uri.find(':') != -1:
  5484.                 match = re.match('(ipp|https?)://([^/]+)(.*)', device.uri)
  5485.                 if match:
  5486.                     server = match.group(2)
  5487.                     printer = match.group(3)
  5488.                 else:
  5489.                     server = ''
  5490.                     printer = ''
  5491.                 self.entNPTIPPHostname.set_text(server)
  5492.                 self.entNPTIPPQueuename.set_text(printer)
  5493.                 self.lblIPPURI.set_text(device.uri)
  5494.                 self.lblIPPURI.show()
  5495.                 self.entNPTIPPQueuename.show()
  5496.                 location = server
  5497.             else:
  5498.                 self.entNPTIPPHostname.set_text('')
  5499.                 self.entNPTIPPQueuename.set_text('/printers/')
  5500.                 self.entNPTIPPQueuename.show()
  5501.                 self.lblIPPURI.hide()
  5502.         elif device.type == 'lpd':
  5503.             self.cmbentNPTLpdHost.child.set_text('')
  5504.             self.cmbentNPTLpdQueue.child.set_text('')
  5505.             self.cmbentNPTLpdQueue.get_model().clear()
  5506.             self.btnNPTLpdProbe.set_sensitive(False)
  5507.             if len(device.uri) > 6:
  5508.                 host = device.uri[6:]
  5509.                 i = host.find('/')
  5510.                 if i != -1:
  5511.                     printer = host[i + 1:]
  5512.                     host = host[:i]
  5513.                 else:
  5514.                     printer = ''
  5515.                 self.cmbentNPTLpdHost.child.set_text(host)
  5516.                 self.cmbentNPTLpdQueue.child.set_text(printer)
  5517.                 location = host
  5518.                 self.btnNPTLpdProbe.set_sensitive(True)
  5519.             
  5520.         elif device.uri == 'smb':
  5521.             self.entSMBURI.set_text('')
  5522.             self.btnSMBVerify.set_sensitive(False)
  5523.         elif device.type == 'smb':
  5524.             self.entSMBUsername.set_text('')
  5525.             self.entSMBPassword.set_text('')
  5526.             self.entSMBURI.set_text(device.uri[6:])
  5527.             self.btnSMBVerify.set_sensitive(True)
  5528.         else:
  5529.             self.entNPTDevice.set_text(device.uri)
  5530.         
  5531.         try:
  5532.             if len(location) == 0 and self.device.device_class == 'direct':
  5533.                 if self.mainapp.connect_server == 'localhost' or self.mainapp.connect_server[0] == '/':
  5534.                     u = os.uname()
  5535.                     location = u[1]
  5536.                 else:
  5537.                     location = self.mainapp.connect_server
  5538.             
  5539.             self.entNPLocation.set_text(location)
  5540.         except:
  5541.             nonfatalException()
  5542.  
  5543.         self.setNPButtons()
  5544.  
  5545.     
  5546.     def on_cmbentNPTLpdHost_changed(self, cmbent):
  5547.         hostname = cmbent.get_active_text()
  5548.         self.btnNPTLpdProbe.set_sensitive(len(hostname) > 0)
  5549.         self.setNPButtons()
  5550.  
  5551.     
  5552.     def on_btnNPTLpdProbe_clicked(self, button):
  5553.         hostname = self.cmbentNPTLpdHost.get_active_text()
  5554.         server = probe_printer.LpdServer(hostname)
  5555.         self.lblWait.set_markup('<span weight="bold" size="larger">' + _('Searching') + '</span>\n\n' + _('Searching for printers'))
  5556.         self.WaitWindow.set_transient_for(self.NewPrinterWindow)
  5557.         self.WaitWindow.show_now()
  5558.         self.busy(self.WaitWindow)
  5559.         printers = server.probe()
  5560.         self.WaitWindow.hide()
  5561.         model = self.cmbentNPTLpdQueue.get_model()
  5562.         model.clear()
  5563.         for printer in printers:
  5564.             self.cmbentNPTLpdQueue.append_text(printer)
  5565.         
  5566.         if printers:
  5567.             self.cmbentNPTLpdQueue.set_active(0)
  5568.         
  5569.  
  5570.     
  5571.     def on_entNPTNetworkHostname_changed(self, ent):
  5572.         s = ent.get_text()
  5573.         self.btnNetworkFind.set_sensitive(len(s) > 0)
  5574.         self.lblNetworkFindNotFound.hide()
  5575.         self.setNPButtons()
  5576.  
  5577.     
  5578.     def on_btnNetworkFind_clicked(self, button):
  5579.         host = self.entNPTNetworkHostname.get_text()
  5580.         
  5581.         def found_callback(new_device):
  5582.             glib.idle_add(self.found_network_printer_callback, new_device)
  5583.  
  5584.         self.btnNetworkFind.set_sensitive(False)
  5585.         self.entNPTNetworkHostname.set_sensitive(False)
  5586.         self.network_found = 0
  5587.         self.lblNetworkFindSearching.show_all()
  5588.         finder = probe_printer.PrinterFinder()
  5589.         self.imgProcessWorking.show()
  5590.         self.spinner.start()
  5591.         finder.find(host, found_callback)
  5592.  
  5593.     
  5594.     def found_network_printer_callback(self, new_device):
  5595.         if new_device:
  5596.             self.network_found += 1
  5597.             dev = PhysicalDevice(new_device)
  5598.             
  5599.             try:
  5600.                 i = self.devices.index(dev)
  5601.                 self.devices[i].add_device(new_device)
  5602.                 (path, column) = self.tvNPDevices.get_cursor()
  5603.                 model = self.tvNPDevices.get_model()
  5604.                 iter = model.get_iter(path)
  5605.                 if model.get_value(iter, 1) == self.devices[i]:
  5606.                     self.on_tvNPDevices_cursor_changed(self.tvNPDevices)
  5607.             except ValueError:
  5608.                 self
  5609.                 self
  5610.                 dev.set_data('checked-hplip', True)
  5611.                 self.devices.append(dev)
  5612.                 self.devices.sort()
  5613.                 model = self.tvNPDevices.get_model()
  5614.                 iter = model.insert_before(None, self.devices_find_nw_iter, row = [
  5615.                     dev.get_info(),
  5616.                     dev,
  5617.                     False])
  5618.             except:
  5619.                 self
  5620.  
  5621.             if self.network_found == 1:
  5622.                 path = model.get_path(iter)
  5623.                 self.tvNPDevices.set_cursor(path)
  5624.             
  5625.         else:
  5626.             self.imgProcessWorking.hide()
  5627.             self.spinner.stop()
  5628.             self.lblNetworkFindSearching.hide()
  5629.             self.entNPTNetworkHostname.set_sensitive(True)
  5630.             self.btnNetworkFind.set_sensitive(True)
  5631.             if self.network_found == 0:
  5632.                 self.lblNetworkFindNotFound.set_markup('<i>' + _('No printer was found at that address.') + '</i>')
  5633.                 self.lblNetworkFindNotFound.show()
  5634.             
  5635.  
  5636.     
  5637.     def getDeviceURI(self):
  5638.         type = self.device.type
  5639.         page = self.new_printer_device_tabs.get(type, 1)
  5640.         device = type
  5641.         if page == 0:
  5642.             device = self.device.uri
  5643.         elif type == 'socket':
  5644.             host = self.entNPTDirectJetHostname.get_text()
  5645.             port = self.entNPTDirectJetPort.get_text()
  5646.             if host:
  5647.                 device += '://' + host
  5648.                 if port:
  5649.                     device += ':' + port
  5650.                 
  5651.             
  5652.         elif type in ('ipp', 'http', 'https'):
  5653.             if self.lblIPPURI.get_property('visible'):
  5654.                 device = self.lblIPPURI.get_text()
  5655.             
  5656.         elif type == 'lpd':
  5657.             host = self.cmbentNPTLpdHost.get_active_text()
  5658.             printer = self.cmbentNPTLpdQueue.get_active_text()
  5659.             if host:
  5660.                 device += '://' + host
  5661.                 if printer:
  5662.                     device += '/' + printer
  5663.                 
  5664.             
  5665.         elif type == 'serial':
  5666.             options = []
  5667.             for widget, name, optionvalues in ((self.cmbNPTSerialBaud, 'baud', None), (self.cmbNPTSerialBits, 'bits', None), (self.cmbNPTSerialParity, 'parity', ('none', 'odd', 'even')), (self.cmbNPTSerialFlow, 'flow', ('none', 'soft', 'hard', 'hard'))):
  5668.                 nr = widget.get_active()
  5669.                 if nr:
  5670.                     if optionvalues is not None:
  5671.                         option = optionvalues[nr - 1]
  5672.                     else:
  5673.                         option = widget.get_active_text()
  5674.                     options.append(name + '=' + option)
  5675.                     continue
  5676.             
  5677.             options = '+'.join(options)
  5678.             device = self.device.uri.split('?')[0]
  5679.             if options:
  5680.                 device = device + '?' + options
  5681.             
  5682.         elif type == 'smb':
  5683.             uri = self.entSMBURI.get_text()
  5684.             (group, host, share, u, p) = SMBURI(uri = uri).separate()
  5685.             user = ''
  5686.             password = ''
  5687.             if self.rbtnSMBAuthSet.get_active():
  5688.                 user = self.entSMBUsername.get_text()
  5689.                 password = self.entSMBPassword.get_text()
  5690.             
  5691.             uri = SMBURI(group = group, host = host, share = share, user = user, password = password).get_uri()
  5692.             if uri:
  5693.                 device += '://' + uri
  5694.             
  5695.         else:
  5696.             device = self.entNPTDevice.get_text()
  5697.         return device
  5698.  
  5699.     
  5700.     def on_rbtnNPFoomatic_toggled(self, widget):
  5701.         rbtn1 = self.rbtnNPFoomatic.get_active()
  5702.         rbtn2 = self.rbtnNPPPD.get_active()
  5703.         rbtn3 = self.rbtnNPDownloadableDriverSearch.get_active()
  5704.         self.tvNPMakes.set_sensitive(rbtn1)
  5705.         self.filechooserPPD.set_sensitive(rbtn2)
  5706.         if rbtn1:
  5707.             page = 0
  5708.         
  5709.         if rbtn2:
  5710.             page = 1
  5711.         
  5712.         if rbtn3:
  5713.             page = 2
  5714.         
  5715.         self.ntbkPPDSource.set_current_page(page)
  5716.         if not rbtn3 and self.openprinting_query_handle:
  5717.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5718.             self.openprinting_query_handle = None
  5719.             self.btnNPDownloadableDriverSearch_label.set_text(_('Search'))
  5720.             model = gtk.ListStore(str, str)
  5721.             combobox = self.cmbNPDownloadableDriverFoundPrinters
  5722.             combobox.set_model(model)
  5723.             combobox.set_sensitive(False)
  5724.         
  5725.         for widget in [
  5726.             self.entNPDownloadableDriverSearch,
  5727.             self.cmbNPDownloadableDriverFoundPrinters]:
  5728.             widget.set_sensitive(rbtn3)
  5729.         
  5730.         if rbtn3:
  5731.             pass
  5732.         self.btnNPDownloadableDriverSearch.set_sensitive(self.openprinting_query_handle == None)
  5733.         self.setNPButtons()
  5734.  
  5735.     
  5736.     def on_filechooserPPD_selection_changed(self, widget):
  5737.         self.setNPButtons()
  5738.  
  5739.     
  5740.     def on_btnNPDownloadableDriverSearch_clicked(self, widget):
  5741.         if self.openprinting_query_handle != None:
  5742.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5743.             self.openprinting_query_handle = None
  5744.         
  5745.         widget.set_sensitive(False)
  5746.         label = self.btnNPDownloadableDriverSearch_label
  5747.         label.set_text(_('Searching'))
  5748.         searchterm = self.entNPDownloadableDriverSearch.get_text()
  5749.         self.openprinting_query_handle = self.openprinting.searchPrinters(searchterm, self.openprinting_printers_found)
  5750.         self.cmbNPDownloadableDriverFoundPrinters.set_sensitive(False)
  5751.  
  5752.     
  5753.     def openprinting_printers_found(self, status, user_data, printers):
  5754.         self.openprinting_query_handle = None
  5755.         button = self.btnNPDownloadableDriverSearch
  5756.         label = self.btnNPDownloadableDriverSearch_label
  5757.         gtk.gdk.threads_enter()
  5758.         
  5759.         try:
  5760.             label.set_text(_('Search'))
  5761.             button.set_sensitive(True)
  5762.             if status != 0:
  5763.                 print printers
  5764.                 print traceback.extract_tb(printers[2], limit = None)
  5765.                 gtk.gdk.threads_leave()
  5766.                 return None
  5767.             model = gtk.ListStore(str, str)
  5768.             sorted_list = []
  5769.             for id, name in printers.iteritems():
  5770.                 sorted_list.append((id, name))
  5771.             
  5772.             sorted_list.sort((lambda x, y: cups.modelSort(x[1], y[1])))
  5773.             sought = self.entNPDownloadableDriverSearch.get_text().lower()
  5774.             select_index = 0
  5775.             for id, name in sorted_list:
  5776.                 iter = model.append(None)
  5777.                 model.set_value(iter, 0, name)
  5778.                 model.set_value(iter, 1, id)
  5779.                 if name.lower() == sought:
  5780.                     select_index = model.get_path(iter)[0]
  5781.                     continue
  5782.                 None if len(printers) != 1 else status != 0
  5783.             
  5784.             combobox = self.cmbNPDownloadableDriverFoundPrinters
  5785.             combobox.set_model(model)
  5786.             combobox.set_active(select_index)
  5787.             combobox.set_sensitive(True)
  5788.             self.setNPButtons()
  5789.         except:
  5790.             nonfatalException()
  5791.  
  5792.         gtk.gdk.threads_leave()
  5793.  
  5794.     
  5795.     def on_cmbNPDownloadableDriverFoundPrinters_changed(self, widget):
  5796.         self.setNPButtons()
  5797.         if self.openprinting_query_handle != None:
  5798.             self.openprinting.cancelOperation(self.openprinting_query_handle)
  5799.             self.openprinting_query_handle = None
  5800.             self.drivers_lock.release()
  5801.         
  5802.         model = widget.get_model()
  5803.         iter = widget.get_active_iter()
  5804.         if iter:
  5805.             id = model.get_value(iter, 1)
  5806.         else:
  5807.             id = None
  5808.         if id == None:
  5809.             return None
  5810.         debugprint('Query drivers for %s' % id)
  5811.         self.drivers_lock.acquire(0)
  5812.         extra_options = dict()
  5813.         if self.DOWNLOADABLE_ONLYPPD:
  5814.             extra_options['onlyppdfiles'] = '1'
  5815.         
  5816.         self.openprinting_query_handle = self.openprinting.listDrivers(id, self.openprinting_drivers_found, extra_options = extra_options)
  5817.  
  5818.     
  5819.     def openprinting_drivers_found(self, status, user_data, drivers):
  5820.         if status != 0:
  5821.             print drivers
  5822.             print traceback.extract_tb(drivers[2], limit = None)
  5823.             return None
  5824.         self.openprinting_query_handle = None
  5825.         self.downloadable_drivers = drivers
  5826.         debugprint('Drivers query completed: %s' % drivers.keys())
  5827.         self.drivers_lock.release()
  5828.  
  5829.     
  5830.     def fillDownloadableDrivers(self):
  5831.         self.lblNPDownloadableDriverSupplier.set_text('')
  5832.         self.lblNPDownloadableDriverLicense.set_text('')
  5833.         self.lblNPDownloadableDriverDescription.set_text('')
  5834.         self.lblNPDownloadableDriverSupportContacts.set_text('')
  5835.         self.rbtnNPDownloadLicenseNo.set_active(True)
  5836.         self.frmNPDownloadableDriverLicenseTerms.hide()
  5837.         drivers = self.downloadable_drivers
  5838.         model = gtk.ListStore(str, gobject.TYPE_PYOBJECT)
  5839.         recommended_iter = None
  5840.         first_iter = None
  5841.         for driver in drivers.values():
  5842.             iter = model.append(None)
  5843.             if first_iter == None:
  5844.                 first_iter = iter
  5845.             
  5846.             model.set_value(iter, 0, driver['name'])
  5847.             model.set_value(iter, 1, driver)
  5848.             if driver['recommended']:
  5849.                 recommended_iter = iter
  5850.                 continue
  5851.         
  5852.         if recommended_iter == None:
  5853.             recommended_iter = first_iter
  5854.         
  5855.         treeview = self.tvNPDownloadableDrivers
  5856.         treeview.set_model(model)
  5857.         if recommended_iter != None:
  5858.             treeview.get_selection().select_iter(recommended_iter)
  5859.         
  5860.  
  5861.     
  5862.     def on_rbtnNPDownloadLicense_toggled(self, widget):
  5863.         self.setNPButtons()
  5864.  
  5865.     
  5866.     def fillMakeList(self):
  5867.         makes = self.ppds.getMakes()
  5868.         model = self.tvNPMakes.get_model()
  5869.         model.clear()
  5870.         found = False
  5871.         auto_make_lower = self.auto_make.lower()
  5872.         for make in makes:
  5873.             iter = model.append((make,))
  5874.             if make.lower() == auto_make_lower:
  5875.                 path = model.get_path(iter)
  5876.                 self.tvNPMakes.set_cursor(path)
  5877.                 self.tvNPMakes.scroll_to_cell(path, None, True, 0.5, 0.5)
  5878.                 found = True
  5879.                 continue
  5880.         
  5881.         if not found:
  5882.             self.tvNPMakes.set_cursor(0)
  5883.             self.tvNPMakes.scroll_to_cell(0, None, True, 0, 0)
  5884.         
  5885.         search = ''
  5886.         if self.device and self.device.id_dict:
  5887.             devid_dict = self.device.id_dict
  5888.             if devid_dict['MFG'] and devid_dict['MDL']:
  5889.                 search = devid_dict['MFG'] + ' ' + devid_dict['MDL']
  5890.             elif devid_dict['DES']:
  5891.                 search = devid_dict['DES']
  5892.             elif devid_dict['MFG']:
  5893.                 search = devid_dict['MFG']
  5894.             
  5895.         
  5896.         if search == '' and self.auto_make != None:
  5897.             search += self.auto_make
  5898.             if self.auto_model != None:
  5899.                 search += ' ' + self.auto_model
  5900.             
  5901.         
  5902.         self.entNPDownloadableDriverSearch.set_text(search)
  5903.  
  5904.     
  5905.     def on_tvNPMakes_cursor_changed(self, tvNPMakes):
  5906.         (path, column) = tvNPMakes.get_cursor()
  5907.         if path != None:
  5908.             model = tvNPMakes.get_model()
  5909.             iter = model.get_iter(path)
  5910.             self.NPMake = model.get(iter, 0)[0]
  5911.             self.fillModelList()
  5912.         
  5913.  
  5914.     
  5915.     def fillModelList(self):
  5916.         models = self.ppds.getModels(self.NPMake)
  5917.         model = self.tvNPModels.get_model()
  5918.         model.clear()
  5919.         selected = False
  5920.         is_auto_make = self.NPMake.lower() == self.auto_make.lower()
  5921.         if is_auto_make:
  5922.             auto_model_lower = self.auto_model.lower()
  5923.         
  5924.         for pmodel in models:
  5925.             iter = model.append((pmodel,))
  5926.             if is_auto_make and pmodel.lower() == auto_model_lower:
  5927.                 path = model.get_path(iter)
  5928.                 self.tvNPModels.set_cursor(path)
  5929.                 self.tvNPModels.scroll_to_cell(path, None, True, 0.5, 0.5)
  5930.                 selected = True
  5931.                 continue
  5932.         
  5933.         if not selected:
  5934.             self.tvNPModels.set_cursor(0)
  5935.             self.tvNPModels.scroll_to_cell(0, None, True, 0, 0)
  5936.         
  5937.         self.tvNPModels.columns_autosize()
  5938.  
  5939.     
  5940.     def fillDriverList(self, pmake, pmodel):
  5941.         self.NPModel = pmodel
  5942.         model = self.tvNPDrivers.get_model()
  5943.         model.clear()
  5944.         ppds = self.ppds.getInfoFromModel(pmake, pmodel)
  5945.         self.NPDrivers = self.ppds.orderPPDNamesByPreference(ppds.keys(), self.jockey_installed_files)
  5946.         for i in range(len(self.NPDrivers)):
  5947.             ppd = ppds[self.NPDrivers[i]]
  5948.             driver = ppd['ppd-make-and-model']
  5949.             driver = driver.replace(' (recommended)', '')
  5950.             
  5951.             try:
  5952.                 lpostfix = ' [%s]' % ppd['ppd-natural-language']
  5953.                 driver += lpostfix
  5954.             except KeyError:
  5955.                 pass
  5956.  
  5957.             if i == 0:
  5958.                 iter = model.append((driver + _(' (recommended)'),))
  5959.                 path = model.get_path(iter)
  5960.                 self.tvNPDrivers.get_selection().select_path(path)
  5961.                 self.tvNPDrivers.scroll_to_cell(path, None, True, 0.5, 0)
  5962.                 continue
  5963.             model.append((driver,))
  5964.         
  5965.         self.tvNPDrivers.columns_autosize()
  5966.  
  5967.     
  5968.     def on_NPDrivers_query_tooltip(self, tv, x, y, keyboard_mode, tooltip):
  5969.         drivername = self.NPDrivers[path[0]]
  5970.         ppddict = self.ppds.getInfoFromPPDName(drivername)
  5971.         markup = ppddict['ppd-make-and-model']
  5972.         if drivername.startswith('foomatic:'):
  5973.             markup += ' '
  5974.             markup += _('This PPD is generated by foomatic.')
  5975.         
  5976.         tooltip.set_markup(markup)
  5977.         return True
  5978.  
  5979.     
  5980.     def on_tvNPModels_cursor_changed(self, widget):
  5981.         (path, column) = widget.get_cursor()
  5982.         if path != None:
  5983.             model = widget.get_model()
  5984.             iter = model.get_iter(path)
  5985.             pmodel = model.get(iter, 0)[0]
  5986.             self.fillDriverList(self.NPMake, pmodel)
  5987.             self.on_tvNPDrivers_cursor_changed(self.tvNPDrivers)
  5988.         
  5989.  
  5990.     
  5991.     def on_tvNPDrivers_cursor_changed(self, widget):
  5992.         self.setNPButtons()
  5993.  
  5994.     
  5995.     def on_tvNPDownloadableDrivers_cursor_changed(self, widget):
  5996.         (model, iter) = widget.get_selection().get_selected()
  5997.         if not iter:
  5998.             (path, column) = widget.get_cursor()
  5999.             iter = model.get_iter(path)
  6000.         
  6001.         driver = model.get_value(iter, 1)
  6002.         import pprint
  6003.         pprint.pprint(driver)
  6004.         self.ntbkNPDownloadableDriverProperties.set_current_page(1)
  6005.         supplier = driver.get('supplier', _('OpenPrinting'))
  6006.         vendor = self.cbNPDownloadableDriverSupplierVendor
  6007.         active = driver['manufacturersupplied']
  6008.         
  6009.         def set_protect_active(widget, active):
  6010.             widget.set_active(active)
  6011.             widget.set_data('protect_active', active)
  6012.  
  6013.         set_protect_active(vendor, active)
  6014.         self.lblNPDownloadableDriverSupplier.set_text(supplier)
  6015.         license = driver.get('license', _('Distributable'))
  6016.         patents = self.cbNPDownloadableDriverLicensePatents
  6017.         free = self.cbNPDownloadableDriverLicenseFree
  6018.         set_protect_active(patents, driver['patents'])
  6019.         set_protect_active(free, driver['freesoftware'])
  6020.         self.lblNPDownloadableDriverLicense.set_text(license)
  6021.         description = driver.get('shortdescription', _('None'))
  6022.         self.lblNPDownloadableDriverDescription.set_markup(description)
  6023.         functionality = driver['functionality']
  6024.         for field in [
  6025.             'Graphics',
  6026.             'LineArt',
  6027.             'Photo',
  6028.             'Text']:
  6029.             key = field.lower()
  6030.             value = None
  6031.             hs = self.__dict__.get('hsDownloadableDriverPerf%s' % field)
  6032.             unknown = self.__dict__.get('lblDownloadableDriverPerf%sUnknown' % field)
  6033.             if functionality.has_key(key):
  6034.                 if hs:
  6035.                     
  6036.                     try:
  6037.                         value = int(functionality[key])
  6038.                         hs.set_value(value)
  6039.                         hs.show_all()
  6040.                         unknown.hide()
  6041.  
  6042.                 
  6043.             
  6044.             if value == None:
  6045.                 hs.hide()
  6046.                 unknown.show_all()
  6047.                 continue
  6048.         
  6049.         supportcontacts = ''
  6050.         if driver.has_key('supportcontacts'):
  6051.             for supportentry in driver['supportcontacts']:
  6052.                 if supportentry['name']:
  6053.                     supportcontact = ' - ' + supportentry['name']
  6054.                     supportcontact_extra = ''
  6055.                     if supportentry['url']:
  6056.                         supportcontact_extra = supportcontact_extra + supportentry['url']
  6057.                     
  6058.                     if supportentry['level']:
  6059.                         if supportcontact_extra:
  6060.                             supportcontact_extra = supportcontact_extra + _(', ')
  6061.                         
  6062.                         supportcontact_extra = supportcontact_extra + supportentry['level']
  6063.                     
  6064.                     if supportcontact_extra:
  6065.                         supportcontact = supportcontact + _('\n(%s)') % supportcontact_extra
  6066.                         if supportcontacts:
  6067.                             supportcontacts = supportcontacts + '\n'
  6068.                         
  6069.                         supportcontacts = supportcontacts + supportcontact
  6070.                     
  6071.                 supportcontact_extra
  6072.             
  6073.         
  6074.         if not supportcontacts:
  6075.             supportcontacts = _('No support contacts known')
  6076.         
  6077.         self.lblNPDownloadableDriverSupportContacts.set_text(supportcontacts)
  6078.         if driver.has_key('licensetext'):
  6079.             self.frmNPDownloadableDriverLicenseTerms.show()
  6080.             terms = driver.get('licensetext', _('Not specified.'))
  6081.             self.tvNPDownloadableDriverLicense.get_buffer().set_text(terms)
  6082.         else:
  6083.             self.frmNPDownloadableDriverLicenseTerms.hide()
  6084.         if not driver['nonfreesoftware'] and not driver['patents']:
  6085.             self.rbtnNPDownloadLicenseYes.set_active(True)
  6086.             self.rbtnNPDownloadLicenseYes.hide()
  6087.             self.rbtnNPDownloadLicenseNo.hide()
  6088.         else:
  6089.             self.rbtnNPDownloadLicenseNo.set_active(True)
  6090.             self.rbtnNPDownloadLicenseYes.show()
  6091.             self.rbtnNPDownloadLicenseNo.show()
  6092.             self.frmNPDownloadableDriverLicenseTerms.show()
  6093.             terms = driver.get('licensetext', _('Not specified.'))
  6094.             self.tvNPDownloadableDriverLicense.get_buffer().set_text(terms)
  6095.         self.setNPButtons()
  6096.  
  6097.     
  6098.     def getNPPPD(self):
  6099.         
  6100.         try:
  6101.             if self.rbtnNPFoomatic.get_active():
  6102.                 (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  6103.                 nr = model.get_path(iter)[0]
  6104.                 ppd = self.NPDrivers[nr]
  6105.             elif self.rbtnNPPPD.get_active():
  6106.                 ppd = cups.PPD(self.filechooserPPD.get_filename())
  6107.             else:
  6108.                 treeview = self.tvNPDownloadableDrivers
  6109.                 (model, iter) = treeview.get_selection().get_selected()
  6110.                 driver = model.get_value(iter, 1)
  6111.                 if driver.has_key('ppds'):
  6112.                     if len(driver['ppds']) > 0:
  6113.                         file_to_download = driver['ppds'][0]
  6114.                         debugprint('ppd file to download [' + file_to_download + ']')
  6115.                         file_to_download = file_to_download.strip()
  6116.                         if len(file_to_download) > 0:
  6117.                             ppdurlobj = urllib.urlopen(file_to_download)
  6118.                             ppdcontent = ppdurlobj.read()
  6119.                             ppdurlobj.close()
  6120.                             (tmpfd, ppdname) = tempfile.mkstemp()
  6121.                             debugprint(ppdname)
  6122.                             ppdfile = os.fdopen(tmpfd, 'w')
  6123.                             ppdfile.write(ppdcontent)
  6124.                             ppdfile.close()
  6125.                             ppd = cups.PPD(ppdname)
  6126.                             os.unlink(ppdname)
  6127.                         
  6128.                     
  6129.         except RuntimeError:
  6130.             e = None
  6131.             debugprint('RuntimeError: ' + str(e))
  6132.             if self.rbtnNPFoomatic.get_active():
  6133.                 err_title = _('Database error')
  6134.                 err_text = _("The '%s' driver cannot be used with printer '%s %s'.")
  6135.                 (model, iter) = self.tvNPDrivers.get_selection().get_selected()
  6136.                 nr = model.get_path(iter)[0]
  6137.                 driver = self.NPDrivers[nr]
  6138.                 if driver.startswith('gutenprint'):
  6139.                     err = _("You will need to install the '%s' package in order to use this driver.") % 'gutenprint-foomatic'
  6140.                 else:
  6141.                     err = err_text % (driver, self.NPMake, self.NPModel)
  6142.             elif self.rbtnNPPPD.get_active():
  6143.                 err_title = _('PPD error')
  6144.                 filename = self.filechooserPPD.get_filename()
  6145.                 err = _('Failed to read PPD file.  Possible reason follows:') + '\n'
  6146.                 
  6147.                 try:
  6148.                     p = subprocess.Popen([
  6149.                         '/usr/bin/cupstestppd',
  6150.                         '-rvv',
  6151.                         filename], stdin = file('/dev/null'), stdout = subprocess.PIPE, stderr = subprocess.PIPE)
  6152.                     (stdout, stderr) = p.communicate()
  6153.                     err += stdout
  6154.                 raise 
  6155.  
  6156.             else:
  6157.                 err_title = _('Downloadable drivers')
  6158.                 err = _('Failed to download PPD.')
  6159.             show_error_dialog(err_title, err, self.NewPrinterWindow)
  6160.             return None
  6161.         else:
  6162.             debugprint('ppd: ' + repr(ppd))
  6163.             if isinstance(ppd, str) or isinstance(ppd, unicode):
  6164.                 self.mainapp.cups._begin_operation(_('fetching PPD'))
  6165.                 
  6166.                 try:
  6167.                     if ppd != 'raw':
  6168.                         f = self.mainapp.cups.getServerPPD(ppd)
  6169.                         ppd = cups.PPD(f)
  6170.                         os.unlink(f)
  6171.                 except RuntimeError:
  6172.                     nonfatalException()
  6173.                     debugprint('libcups from CUPS 1.3 not available: never mind')
  6174.                 except cups.IPPError:
  6175.                     nonfatalException()
  6176.                     debugprint('CUPS 1.3 server not available: never mind')
  6177.  
  6178.                 self.mainapp.cups._end_operation()
  6179.             
  6180.  
  6181.         return ppd
  6182.  
  6183.     
  6184.     def fillNPInstallableOptions(self):
  6185.         debugprint('Examining installable options')
  6186.         self.installable_options = False
  6187.         self.options = { }
  6188.         container = self.vbNPInstallOptions
  6189.         for child in container.get_children():
  6190.             container.remove(child)
  6191.         
  6192.         if not self.ppd:
  6193.             l = gtk.Label(_('No Installable Options'))
  6194.             container.add(l)
  6195.             l.show()
  6196.             debugprint('No PPD so no installable options')
  6197.             return None
  6198.         for group in self.ppd.optionGroups:
  6199.             if group.name != 'InstallableOptions':
  6200.                 continue
  6201.             
  6202.             self.installable_options = True
  6203.             table = gtk.Table(1, 3, False)
  6204.             table.set_col_spacings(6)
  6205.             table.set_row_spacings(6)
  6206.             container.add(table)
  6207.             rows = 0
  6208.             for nr, option in enumerate(group.options):
  6209.                 if option.keyword == 'PageRegion':
  6210.                     continue
  6211.                 
  6212.                 rows += 1
  6213.                 table.resize(rows, 3)
  6214.                 o = OptionWidget(option, self.ppd, self)
  6215.                 table.attach(o.conflictIcon, 0, 1, nr, nr + 1, 0, 0, 0, 0)
  6216.                 hbox = gtk.HBox()
  6217.                 if o.label:
  6218.                     a = gtk.Alignment(0.5, 0.5, 1, 1)
  6219.                     a.set_padding(0, 0, 0, 6)
  6220.                     a.add(o.label)
  6221.                     table.attach(a, 1, 2, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6222.                     table.attach(hbox, 2, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6223.                 else:
  6224.                     table.attach(hbox, 1, 3, nr, nr + 1, gtk.FILL, 0, 0, 0)
  6225.                 hbox.pack_start(o.selector, False)
  6226.                 self.options[option.keyword] = o
  6227.             
  6228.         
  6229.         if not self.installable_options:
  6230.             l = gtk.Label(_('No Installable Options'))
  6231.             container.add(l)
  6232.             l.show()
  6233.         
  6234.         self.scrNPInstallableOptions.hide()
  6235.         self.scrNPInstallableOptions.show_all()
  6236.  
  6237.     
  6238.     def on_btnNPApply_clicked(self, widget):
  6239.         if self.dialog_mode in ('class', 'printer', 'printer_with_uri'):
  6240.             name = unicode(self.entNPName.get_text())
  6241.             location = unicode(self.entNPLocation.get_text())
  6242.             info = unicode(self.entNPDescription.get_text())
  6243.         else:
  6244.             name = self.mainapp.printer.name
  6245.         check = False
  6246.         checkppd = None
  6247.         ppd = self.ppd
  6248.         if self.dialog_mode == 'class':
  6249.             members = getCurrentClassMembers(self.tvNCMembers)
  6250.             
  6251.             try:
  6252.                 for member in members:
  6253.                     self.mainapp.cups.addPrinterToClass(member, name)
  6254.             except cups.IPPError:
  6255.                 (e, msg) = None
  6256.                 self.show_IPP_Error(e, msg)
  6257.                 return None
  6258.             
  6259.  
  6260.         None<EXCEPTION MATCH>cups.IPPError
  6261.         if self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri':
  6262.             uri = None
  6263.             if self.device.uri:
  6264.                 uri = self.device.uri
  6265.             else:
  6266.                 uri = self.getDeviceURI()
  6267.             if not self.ppd:
  6268.                 self.nextNPTab(-1)
  6269.                 return None
  6270.             for option in self.options.itervalues():
  6271.                 option.writeback()
  6272.             
  6273.             self.busy(self.NewPrinterWindow)
  6274.             while gtk.events_pending():
  6275.                 gtk.main_iteration()
  6276.                 continue
  6277.                 self.ppd
  6278.             self.mainapp.cups._begin_operation(_('adding printer %s') % name)
  6279.             
  6280.             try:
  6281.                 if isinstance(ppd, str) or isinstance(ppd, unicode):
  6282.                     self.mainapp.cups.addPrinter(name, ppdname = ppd, device = uri, info = info, location = location)
  6283.                     check = True
  6284.                 elif ppd is None:
  6285.                     self.mainapp.cups.addPrinter(name, device = uri, info = info, location = location)
  6286.                 else:
  6287.                     cupshelpers.setPPDPageSize(ppd, self.language[0])
  6288.                     self.mainapp.cups.addPrinter(name, ppd = ppd, device = uri, info = info, location = location)
  6289.                     check = True
  6290.                     checkppd = ppd
  6291.             except cups.IPPError:
  6292.                 (e, msg) = None
  6293.                 self.ready(self.NewPrinterWindow)
  6294.                 self.show_IPP_Error(e, msg)
  6295.                 self.mainapp.cups._end_operation()
  6296.                 return None
  6297.                 self.ready(self.NewPrinterWindow)
  6298.                 self.mainapp.cups._end_operation()
  6299.                 fatalException(1)
  6300.  
  6301.             self.mainapp.cups._end_operation()
  6302.             self.ready(self.NewPrinterWindow)
  6303.         
  6304.         if self.dialog_mode in ('class', 'printer', 'printer_with_uri'):
  6305.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6306.             
  6307.             try:
  6308.                 cupshelpers.activateNewPrinter(self.mainapp.cups, name)
  6309.                 self.mainapp.cups.setPrinterLocation(name, location)
  6310.                 self.mainapp.cups.setPrinterInfo(name, info)
  6311.             except cups.IPPError:
  6312.                 (e, msg) = None
  6313.                 self.show_IPP_Error(e, msg)
  6314.                 self.mainapp.cups._end_operation()
  6315.                 return None
  6316.  
  6317.             self.mainapp.cups._end_operation()
  6318.         elif self.dialog_mode == 'device':
  6319.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6320.             
  6321.             try:
  6322.                 uri = self.getDeviceURI()
  6323.                 if not self.install_hplip_plugin(uri):
  6324.                     self.on_NPCancel(None)
  6325.                     return None
  6326.                 self.mainapp.cups.addPrinter(name, device = uri)
  6327.             except cups.IPPError:
  6328.                 (e, msg) = None
  6329.                 self.show_IPP_Error(e, msg)
  6330.                 self.mainapp.cups._end_operation()
  6331.                 return None
  6332.  
  6333.             self.mainapp.cups._end_operation()
  6334.         elif self.dialog_mode == 'ppd':
  6335.             if not ppd:
  6336.                 ppd = self.ppd = self.getNPPPD()
  6337.                 if not ppd:
  6338.                     self.nextNPTab(-1)
  6339.                     return None
  6340.             
  6341.             self.mainapp.cups._begin_operation(_('modifying printer %s') % name)
  6342.             raw = False
  6343.             if isinstance(ppd, str) or isinstance(ppd, unicode):
  6344.                 if self.rbtnChangePPDasIs.get_active():
  6345.                     
  6346.                     try:
  6347.                         self.mainapp.cups.addPrinter(name, ppdname = 'raw')
  6348.                     except cups.IPPError:
  6349.                         (e, msg) = None
  6350.                         self.show_IPP_Error(e, msg)
  6351.                     except:
  6352.                         None<EXCEPTION MATCH>cups.IPPError
  6353.                     
  6354.  
  6355.                 None<EXCEPTION MATCH>cups.IPPError
  6356.                 
  6357.                 try:
  6358.                     self.mainapp.cups.addPrinter(name, ppdname = ppd)
  6359.                 except cups.IPPError:
  6360.                     (e, msg) = None
  6361.                     self.show_IPP_Error(e, msg)
  6362.                     self.mainapp.cups._end_operation()
  6363.                     return None
  6364.  
  6365.                 
  6366.                 try:
  6367.                     filename = self.mainapp.cups.getPPD(name)
  6368.                     ppd = cups.PPD(filename)
  6369.                     os.unlink(filename)
  6370.                 except cups.IPPError:
  6371.                     (e, msg) = None
  6372.                     if e == cups.IPP_NOT_FOUND:
  6373.                         raw = True
  6374.                     else:
  6375.                         self.show_IPP_Error(e, msg)
  6376.                         self.mainapp.cups._end_operation()
  6377.                         return None
  6378.                     e == cups.IPP_NOT_FOUND
  6379.                 
  6380.  
  6381.             None<EXCEPTION MATCH>cups.IPPError
  6382.             if not self.rbtnChangePPDasIs.get_active() and isinstance(self.mainapp.ppd, cups.PPD):
  6383.                 cupshelpers.copyPPDOptions(self.mainapp.ppd, ppd)
  6384.             else:
  6385.                 for option in self.options.itervalues():
  6386.                     option.writeback()
  6387.                 
  6388.                 cupshelpers.setPPDPageSize(ppd, self.language[0])
  6389.             
  6390.             try:
  6391.                 self.mainapp.cups.addPrinter(name, ppd = ppd)
  6392.             except cups.IPPError:
  6393.                 (e, msg) = None
  6394.                 self.show_IPP_Error(e, msg)
  6395.  
  6396.             self.mainapp.cups._end_operation()
  6397.             if not raw:
  6398.                 check = True
  6399.                 checkppd = ppd
  6400.             
  6401.         
  6402.         self.NewPrinterWindow.hide()
  6403.         self.mainapp.populateList()
  6404.         dests_iconview = self.mainapp.dests_iconview
  6405.         model = dests_iconview.get_model()
  6406.         iter = model.get_iter_first()
  6407.         while iter != None:
  6408.             queue = unicode(model.get_value(iter, 2))
  6409.             if queue == name:
  6410.                 path = model.get_path(iter)
  6411.                 dests_iconview.scroll_to_path(path, True, 0.5, 0.5)
  6412.                 dests_iconview.unselect_all()
  6413.                 dests_iconview.set_cursor(path)
  6414.                 dests_iconview.select_path(path)
  6415.                 break
  6416.             
  6417.             iter = model.iter_next(iter)
  6418.         self.mainapp.fillPrinterTab(name)
  6419.         self.mainapp.tvPrinterProperties.set_cursor((0,))
  6420.         if check:
  6421.             
  6422.             try:
  6423.                 self.checkDriverExists(name, ppd = checkppd)
  6424.             except:
  6425.                 nonfatalException()
  6426.  
  6427.             
  6428.             try:
  6429.                 option = self.mainapp.server_side_options['media']
  6430.                 if option.get_current_value() == None:
  6431.                     debugprint('Invalid media option: resetting')
  6432.                     option.reset()
  6433.                     self.mainapp.changed.add(option)
  6434.                     self.mainapp.save_printer(self.mainapp.printer)
  6435.             except KeyError:
  6436.                 pass
  6437.             except:
  6438.                 None<EXCEPTION MATCH>KeyError
  6439.                 nonfatalException()
  6440.             
  6441.  
  6442.         None<EXCEPTION MATCH>KeyError
  6443.         if (self.dialog_mode == 'printer' or self.dialog_mode == 'printer_with_uri') and self.mainapp.ppd != False:
  6444.             q = gtk.MessageDialog(self.mainapp.PrintersWindow, gtk.DIALOG_DESTROY_WITH_PARENT | gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _('Would you like to print a test page?'))
  6445.             response = q.run()
  6446.             q.destroy()
  6447.             if response == gtk.RESPONSE_YES:
  6448.                 self.mainapp.display_properties_dialog_for(name)
  6449.                 self.mainapp.PrinterPropertiesDialog.hide()
  6450.                 self.mainapp.btnPrintTestPage.clicked()
  6451.             
  6452.         
  6453.  
  6454.     
  6455.     def checkDriverExists(self, name, ppd = None):
  6456.         '''Check that the driver for an existing queue actually
  6457.         exists, and prompt to install the appropriate package
  6458.         if not.
  6459.  
  6460.         ppd: cups.PPD object, if already created'''
  6461.         server = cups.getServer()
  6462.         if not server == 'localhost' and server == '127.0.0.1' and server == '::1' or server[0] == '/':
  6463.             return None
  6464.         if not ppd:
  6465.             
  6466.             try:
  6467.                 filename = self.mainapp.cups.getPPD(name)
  6468.             except cups.IPPError:
  6469.                 server[0] == '/'
  6470.                 (e, msg) = server[0] == '/'
  6471.                 if e == cups.IPP_NOT_FOUND:
  6472.                     return None
  6473.                 self.show_IPP_Error(e, msg)
  6474.                 return None
  6475.             except:
  6476.                 e == cups.IPP_NOT_FOUND
  6477.  
  6478.             ppd = cups.PPD(filename)
  6479.             os.unlink(filename)
  6480.         
  6481.         (pkgs, exes) = cupshelpers.missingPackagesAndExecutables(ppd)
  6482.         if len(pkgs) > 0 or len(exes) > 0:
  6483.             can_install = False
  6484.             if len(pkgs) > 0:
  6485.                 
  6486.                 try:
  6487.                     pk = installpackage.PackageKit()
  6488.                     can_install = True
  6489.  
  6490.             
  6491.             if can_install and len(pkgs) > 0:
  6492.                 pkg = pkgs[0]
  6493.                 install_text = '<span weight="bold" size="larger">' + _('Install driver') + '</span>\n\n' + _("Printer '%s' requires the %s package but it is not currently installed.") % (name, pkg)
  6494.                 dialog = self.InstallDialog
  6495.                 self.lblInstall.set_markup(install_text)
  6496.                 dialog.set_transient_for(self.mainapp.PrintersWindow)
  6497.                 response = dialog.run()
  6498.                 dialog.hide()
  6499.                 if response == gtk.RESPONSE_OK:
  6500.                     
  6501.                     try:
  6502.                         xid = self.mainapp.PrintersWindow.window.xid
  6503.                         pk.InstallPackageName(xid, 0, pkg)
  6504.  
  6505.                 
  6506.             else:
  6507.                 show_error_dialog(_('Missing driver'), _("Printer '%s' requires the '%s' program but it is not currently installed.  Please install it before using this printer.") % (name, exes + pkgs[0]), self.mainapp.PrintersWindow)
  6508.         
  6509.  
  6510.  
  6511.  
  6512. def main(setup_printer = None, configure_printer = None, change_ppd = False, devid = '', print_test_page = False, focus_on_map = True):
  6513.     cups.setUser(os.environ.get('CUPS_USER', cups.getUser()))
  6514.     gtk.gdk.threads_init()
  6515.     mainwindow = GUI(setup_printer, configure_printer, change_ppd, devid, print_test_page, focus_on_map)
  6516.     if gtk.__dict__.has_key('main'):
  6517.         gtk.main()
  6518.     else:
  6519.         gtk.mainloop()
  6520.  
  6521. if __name__ == '__main__':
  6522.     import getopt
  6523.     
  6524.     try:
  6525.         (opts, args) = getopt.gnu_getopt(sys.argv[1:], '', [
  6526.             'setup-printer=',
  6527.             'configure-printer=',
  6528.             'choose-driver=',
  6529.             'devid=',
  6530.             'print-test-page=',
  6531.             'no-focus-on-map',
  6532.             'debug'])
  6533.     except getopt.GetoptError:
  6534.         show_help()
  6535.         sys.exit(1)
  6536.  
  6537.     setup_printer = None
  6538.     configure_printer = None
  6539.     change_ppd = False
  6540.     print_test_page = False
  6541.     focus_on_map = True
  6542.     devid = ''
  6543.     for opt, optarg in opts:
  6544.         if opt == '--configure-printer' and opt == '--choose-driver' or opt == '--print-test-page':
  6545.             configure_printer = optarg
  6546.             if opt == '--choose-driver':
  6547.                 change_ppd = True
  6548.             elif opt == '--print-test-page':
  6549.                 print_test_page = True
  6550.             
  6551.         elif opt == '--setup-printer':
  6552.             setup_printer = optarg
  6553.         elif opt == '--devid':
  6554.             devid = optarg
  6555.         elif opt == '--no-focus-on-map':
  6556.             focus_on_map = False
  6557.         elif opt == '--debug':
  6558.             set_debugging(True)
  6559.         
  6560.     
  6561.     main(setup_printer, configure_printer, change_ppd, devid, print_test_page, focus_on_map)
  6562.  
  6563.